如何仅对DataFrame的一部分进行更新

时间:2016-02-09 13:00:37

标签: python pandas

假设有一个DataFrame df1INDEXColumn1Column2和另一个df2INDEX,{{1} },Column1

两个Column3都有相似的值,所以我想用它来合并另一个表的信息。

我被告知其他用户如下:

INDEX

如果两个INDEXES具有相似的值,则此方法有效。结果将是df1现在具有df1.update(df2, join='left', overwrite=True) INDEX(来自Column1)和df2(原始来自Column2)。 df1未添加Column3(此行为需要添加所有内容的“df1”命令。)

现在,我想仅在少数情况下更新df1并基于Column2。我认为这样可行:

merge

但事实并非如此;有时我会收到错误,其他命令也可以,但所有df1[df1['Column2'] == 'Cond'].update(df2, join='left', overwrite=True) 值都已修改。

关于如何做到这一点的任何想法?

PS:使用df1将不起作用,因为这要求您搜索的任何INDEX都存在,而事实并非如此。

编辑:附加示例

.loc

1 个答案:

答案 0 :(得分:1)

定义布尔掩码

mask = (df1['Column2'] == 'Cond')

如果df1.index 相同df2.index,则mask可用于选择 来自df2的行 - 即df2.loc[mask]。但如果它们不相同,那么 df2.loc[mask]可能会引发错误(如果len(df1) != len(df2)),或者更糟糕的是,会默默选择错误的行 因为布尔掩码没有在df1df2之间对齐索引值。

因此,在更一般的情况下,当索引不相同时,诀窍是 将布尔掩码转换为可用于限制的Index df2

如果df1.index是唯一的,请在受限df1.update上致电df2

idx = df1.index[mask]
df1.update(df2.loc[idx])

例如,

import pandas as pd
df1 = pd.DataFrame({'Column1':[1,2,3], 'Column2':['Cond',5,'Cond']}, index=['A','B','C'])
#    Column1 Column2
# A        1    Cond
# B        2       5
# C        3    Cond

df2 = pd.DataFrame({'Column1':[10,20,30], 'Column3':[40,50,60]}, index=['D','B','C'])
#    Column1  Column3
# D       10       40
# B       20       50
# C       30       60

mask = df1['Column2'] == 'Cond'
idx = df1.index[mask]
df1.update(df2.loc[idx])
print(df1)

打印

   Column1 Column2
A        1    Cond
B        2       5
C       30    Cond

如果df1.index不是唯一,请通过向其添加mask来使索引唯一:

df1['mask'] = df1['value'] >= 2
df2['mask'] = True
df1 = df1.set_index('mask', append=True)
df2 = df2.set_index('mask', append=True)

然后调用df1.update(df2)会产生所需的结果,因为update会对齐索引。

例如,

import pandas as pd

df1 = pd.DataFrame([['USA',1],['USA',2],['USA',3],['FRA',1],['FRA',2]], 
                   columns = ['country', 'value'])
df2 = pd.DataFrame([['USA',10],['FRA',20]], columns = ['country', 'value'])
df1 = df1.set_index('country')
#          value
# country       
# USA          1
# USA          2
# USA          3
# FRA          1
# FRA          2

df2 = df2.set_index('country')
#          value
# country       
# USA         10
# FRA         20

df1['mask'] = df1['value'] >= 2
df2['mask'] = True
df1 = df1.set_index('mask', append=True)
#                value
# country mask        
# USA     False      1
#         True       2
#         True       3
# FRA     False      1
#         True       2

df2 = df2.set_index('mask', append=True)
#               value
# country mask       
# USA     True     10
# FRA     True     20

df1.update(df2)
df1.index = df1.index.droplevel('mask')
print(df1)

产量

         value
country       
USA          1
USA         10
USA         10
FRA          1
FRA         20