有时带有多个键的字典

问题描述 投票:0回答:3

我有一个 pandas 数据框,我想根据字典值创建一个新列。

这是我的 df 和字典:

data = ['One', 'Two', 'Three', 'Four']

df = pd.DataFrame(data, columns=['Count'])

dictionary = {'One':'Red', 'Two':['Red', 'Blue'], 'Three':'Green','Four':['Green','Red', 'Blue']}

这是我想要达到的结果,

最好使用空白字段而不是 None 值,有人知道方法吗?

我尝试了以下:

df = df = pd.DataFrame([(k, *v) for k, v in dictionary.items()])
df.columns = ['name'] + [f'n{x}' for x in df.columns[1:]]
df

但是,对于没有多个值的键,它似乎将每个字母的实际字符串拆分为列,如下所示:

将值映射到用定界符 (,) 分隔的一列的解决方案也会有所帮助。

python pandas dictionary lambda key-value
3个回答
1
投票

使用

isinstance
检查是否
v
list
并确保您没有将字符串解包为字符:

df = pd.DataFrame([(k, *v) if isinstance(v, list) else (k, v)
                   for k, v in dictionary.items()])
df.columns = ['name'] + [f'n{x}' for x in df.columns[1:]]

输出:

    name     n1    n2    n3
0    One    Red  None  None
1    Two    Red  Blue  None
2  Three  Green  None  None
3   Four  Green   Red  Blue

加入另一个数据框

使用

join
merge
取决于你是想基于索引还是“名称”列进行组合:

df2 = pd.DataFrame([(k, *v) if isinstance(v, list) else (k, v)
                   for k, v in dictionary.items()]
                   ).fillna('')
df2.columns = ['name'] + [f'n{x}' for x in df.columns[1:]]

# if same index 
out = df.join(df2)

# Or merging on a common column
out = df.merge(df2, on='name', how='left')

1
投票

字典的值中有列表,所以需要

if-else
语句来防止
*
解包字符串:

df = pd.DataFrame([(k, *v) 
                   if isinstance(v, list) 
                   else (k, v) for k, v in dictionary.items()])
df.columns = ['name'] + [f'n{x}' for x in df.columns[1:]]
print (df)
    name     n1    n2    n3
0    One    Red  None  None
1    Two    Red  Blue  None
2  Three  Green  None  None
3   Four  Green   Red  Blue

详情

print (((*'Red', )))
('R', 'e', 'd')

print (((*['Red', 'Blue'], )))
('Red', 'Blue')

最好使用空白字段而不是无值,有人知道方法吗?

添加

DataFrame.fillna

df = pd.DataFrame([(k, *v) 
                   if isinstance(v, list) 
                   else (k, v) 
                   for k, v in dictionary.items()]).fillna('')
df.columns = ['name'] + [f'n{x}' for x in df.columns[1:]]
print (df)
    name     n1    n2    n3
0    One    Red            
1    Two    Red  Blue      
2  Three  Green            
3   Four  Green   Red  Blue

如果相同的索引和行数使用

DataFrame.join

df = df_orig.join(df)

如果需要按

name
列合并,按左加入
DataFrame.merge

df = df_orig.merge(df, on='name', how='left')

0
投票

另一种可能的解决方案:

pd.concat([
    df['Count'], 
    pd.DataFrame.from_records([[x, dictionary[x]] for x in dictionary])[1]
    .apply(pd.Series)], axis=1).fillna('')
© www.soinside.com 2019 - 2024. All rights reserved.