基于索引用另一个DataFrame替换Pandas DataFrame中的行

12

我有2个数据框(DataFrame)。

df1
    B   C
A       
0   300 6
1   400 7
2   500 8
3   600 9

df2
    B   C
A       
2   433 99
3   555 99

这是我构建它们的方式:

df1 = pd.DataFrame({'A': [0, 1, 2, 3],
                   'B': [300, 400, 500, 600], 
                   'C': [6, 7, 8, 9]})
df1.set_index('A', inplace=True)
df2 = pd.DataFrame({'A': [2, 3],
                    'B': [433, 555],
                    'C': [99, 99]})
df2.set_index('A', inplace=True)

我想根据索引用来自df2的行替换df1中的所有行,结果应如下所示:

df_result
    B   C
A       
0   300 6
1   400 7
2   433 99
3   555 99

怎样做最优雅?

3个回答

21

这就是update的用途:

df1.update(df2)
>>> df1
       B     C
A             
0  300.0   6.0
1  400.0   7.0
2  433.0  99.0
3  555.0  99.0

唯一的限制是只实现了左连接,保留原始对象的索引和列。这意味着如果df2中有在df1中找不到的索引,则不会添加到df1中。根据使用情况,这可能是一个问题,在这种情况下,df1.combine_first(df2)更好。 - Juho
需要更正我的评论。如果仅需用 df2 中的值替换 df1 中的非空值,则 df1.combine_first(df2) 更好。要使用两个索引的并集更新非空值,需要另一种解决方案。 - Juho

9
尝试使用combine_first
df2.combine_first(df1)

输出:

       B     C
A             
0  300.0   6.0
1  400.0   7.0
2  433.0  99.0
3  555.0  99.0

1
对我来说这不起作用: 结果是df1未改变 - Egirus Ornila
你需要将这个方法的输出重新分配给一个新的数据框,或者将其赋回给df1。这不是像“update”那样的原地方法。尝试使用df_out = df2.combine_first(df1)print(df_out) - Scott Boston
当前的pandas文档表示:“通过使用另一个DataFrame中的非空值填充一个DataFrame中的空值来组合两个DataFrame对象。” 因此,这不再提供原始问题中的行为——非空值不会被覆盖。 - Juho
@Juho 这个例子看起来仍然有效。而且,我不确定这份文档在过去有任何不同。你能提供一个此方法无效的例子吗? - Scott Boston
1
@ScottBoston我的失误,我把df1和df2弄混了。在我的特定用例中,df1实际上是“主”数据表,而df2是我们要对其进行更改的内容(替换单个行并添加新行),但语法df2.combine_first(df1)似乎暗示相反的情况。但是,考虑到df2中所有未更改的行都是null值,并被df1替换,它确实可以发挥作用。 - Juho
如何更新多个列(即匹配到相同的索引,但更新两个或更多列)? - denpy

5

请注意,使用 .loc 不会改变列的类型。

df1.loc[df2.index,:]=df2
df1
Out[20]: 
     B   C
A         
0  300   6
1  400   7
2  433  99
3  555  99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接