问题描述
如果我有一个看起来像这样的数据框:
df = pd.DataFrame({'A': [1,1,2,2],'B': [4,5,6,7,8,9]})
df['C'] = None
A B C
0 1 4 None
1 1 5 None
2 1 6 None
3 2 7 None
4 2 8 None
5 2 9 None
如何将C
的子集设置为相同的字典值?例如,为C
到A==1
的所有行设置{'example': 5}
?
这似乎不起作用:
df.loc[df['A']==1,'C'] = {'example': 5}
解决方法
在这种情况下,您可以使用np.where
df['C'] = np.where(df['A']==1,{'example': 5},df['C'])
输出:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 NaN
4 2 8 NaN
5 2 9 NaN
更新,因为{'example': 5}
是一个可迭代的对象,当您将其分配给列时,Pandas会尝试将其展开,因此如果直接执行,则会出现长度不匹配错误。要为整个列分配该字典,您需要将其包装在另一个与df
相同长度的可迭代对象中:
df['C'] = [{'example':5} for _ in df.index]
输出:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 {'example': 5}
4 2 8 {'example': 5}
5 2 9 {'example': 5}
也就是说,除非确实有必要,否则应尽可能避免在Pandas数据框中出现复杂的对象。
更新2 :根据BEN的评论,也反映在更新
df['C'] = np.where(df['A']==1,df['C'])
可能将同一对象{'example':5}
复制到所有有效行,这可能不是预期的行为。因此,像这样的事情:
df['C'] = [{'example':5} if a==1 else c for a,c in zip(df['A'],df['C'])]
将创建{'example':5'}
的不同副本到相应的行。
您可以使用np.where
:
df['C'] = np.where(df['A']==1,df['C'])
print(df)
打印:
A B C
0 1 4 {'example': 5}
1 1 5 {'example': 5}
2 1 6 {'example': 5}
3 2 7 None
4 2 8 None
5 2 9 None