我有一个 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
但是,对于没有多个值的键,它似乎将每个字母的实际字符串拆分为列,如下所示:
将值映射到用定界符 (,) 分隔的一列的解决方案也会有所帮助。
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')
字典的值中有列表,所以需要
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')
另一种可能的解决方案:
pd.concat([
df['Count'],
pd.DataFrame.from_records([[x, dictionary[x]] for x in dictionary])[1]
.apply(pd.Series)], axis=1).fillna('')