我正在尝试一次更新几个字段 - 我有两个数据源,我正在尝试协调它们。我知道我可以做一些丑陋的合并然后删除列,但是期待下面的代码可以工作:
df = pd.DataFrame([['A','B','C',np.nan,np.nan,np.nan],
['D','E','F',np.nan,np.nan,np.nan],[np.nan,np.nan,np.nan,'a','b','d'],
[np.nan,np.nan,np.nan,'d','e','f']], columns = ['Col1','Col2','Col3','col1_v2','col2_v2','col3_v2'])
print df
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0 A B C NaN NaN NaN
1 D E F NaN NaN NaN
2 NaN NaN NaN a b d
3 NaN NaN NaN d e f
#update
df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']] = df[['col1_v2','col2_v2','col3_v2']]
print df
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0 A B C NaN NaN NaN
1 D E F NaN NaN NaN
2 NaN NaN NaN a b d
3 NaN NaN NaN d e f
我想要的输出是:
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0 A B C NaN NaN NaN
1 D E F NaN NaN NaN
2 a b c a b d
3 d e f d e f
我认为它与切片上的更新/设置有关,但我总是使用.loc更新值,而不是一次更多的列。
我觉得有一种简单的方法可以做到这一点,我只是想念,欢迎任何想法/建议!
编辑以反映下面的解决方案 感谢您对索引的评论。但是,我对此有一个疑问,因为它与系列有关。如果我想以类似的方式更新单个系列,我可以这样做:
df.loc[df['Col1'].isnull(),['Col1']] = df['col1_v2']
print df
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0 A B C NaN NaN NaN
1 D E F NaN NaN NaN
2 a NaN NaN a b d
3 d NaN NaN d e f
请注意,我没有在这里考虑索引,我过滤到2x1系列并将其设置为等于4x1系列,但它正确处理了它。思考?我试图更好地理解我已经使用了一段时间的功能,但我想没有完全掌握底层机制/规则
答案 0 :(得分:14)
你想要替换
print df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']]
Col1 Col2 Col3
2 NaN NaN NaN
3 NaN NaN NaN
使用:
replace_with_this = df.loc[df['Col1'].isnull(),['col1_v2','col2_v2', 'col3_v2']]
print replace_with_this
col1_v2 col2_v2 col3_v2
2 a b d
3 d e f
似乎合理。但是,在执行分配时,需要考虑索引对齐,其中包括列。
所以,这应该有效:
df.loc[df['Col1'].isnull(),['Col1','Col2', 'Col3']] = replace_with_this.values
print df
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
0 A B C NaN NaN NaN
1 D E F NaN NaN NaN
2 a b d a b d
3 d e f d e f
我在最后使用.values
来计算列数。这剥离了replace_with_this
数据框中的列信息,只使用了适当位置的值。
答案 1 :(得分:2)
在“走山路”的精神中,我提供了以下解决方案,产生了所要求的结果。
我意识到这并不完全是你所追求的,因为我没有切片df(以合理的 - 但非功能性 - 你建议的方式)。
#Does not work when indexing on np.nan, so I fill with some arbitrary value.
df = df.fillna('AAA')
#mask to determine which rows to update
mask = df['Col1'] == 'AAA'
#dict with key value pairs for columns to be updated
mp = {'Col1':'col1_v2','Col2':'col2_v2','Col3':'col3_v2'}
#update
for k in mp:
df.loc[mask,k] = df[mp.get(k)]
#swap back np.nans for the arbitrary values
df = df.replace('AAA',np.nan)
输出:
Col1 Col2 Col3 col1_v2 col2_v2 col3_v2
A B C NaN NaN NaN
D E F NaN NaN NaN
a b d a b d
d e f d e f
如果我不替换nans,我得到的错误如下。我将准确研究该错误源自何处。
ValueError: array is not broadcastable to correct shape