我有两个数据帧:
print(df1)
id match
0 1 hello
1 2 there
2 3 NaN
3 4 stack
4 5 NaN
5 6 overflow
6 7 NaN
7 8 hi
8 9 NaN
print(df2)
id match
0 1 NaN
1 2 NaN
2 3 put
3 4 NaN
4 5 new
5 6 NaN
6 7 data
7 8 NaN
8 9 NaN
我想用 df2 中的值填充 df1 中的Nan
。 您可以看到它们共享相同的id
号码。id 3
df1
是Nan
,但我在df2
中有一个值,即put
这个词。
因此,我想通过合并来尽可能填充缺失的值:
df1.merge(df2,how='left',on='id')
id match_x match_y
0 1 hello NaN
1 2 there NaN
2 3 NaN put
3 4 stack NaN
4 5 NaN new
5 6 overflow NaN
6 7 NaN data
7 8 hi NaN
8 9 NaN NaN
你可以看到我得到了_x
和_y
后缀。
我也尝试了内部和外部合并,后缀仍然存在。
我的预期输出。您可以看到大部分数据已填写。
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
在此之后,我想获得一个具有id 9
值的df3
,然后将其合并到 df1 中,等等。
基本上,我想根据"id"使用来自其他数据帧的新值不断更新 df1 中的match
列。
熊猫merge
可以在不添加_x , _y
后缀的情况下使用吗?
我的数据帧:
import pandas as pd
df1 = pd.DataFrame({'id': pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9],dtype='int64',index=pd.RangeIndex(start=0, stop=9, step=1)), 'match': pd.Series(['hello', 'there', nan, 'stack', nan, 'overflow', nan, 'hi', nan],dtype='object',index=pd.RangeIndex(start=0, stop=9, step=1))}, index=pd.RangeIndex(start=0, stop=9, step=1))
df2 = pd.DataFrame({'id': pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9],dtype='int64',index=pd.RangeIndex(start=0, stop=9, step=1)), 'match': pd.Series([nan, nan, 'put', nan, 'new', nan, 'data', nan, nan],dtype='object',index=pd.RangeIndex(start=0, stop=9, step=1))}, index=pd.RangeIndex(start=0, stop=9, step=1))
将Series.fillna
与DataFrame.set_index
一起使用
df1['match'] = (
df1.set_index('id')['match'].fillna(df2.set_index('id')['match']).reset_index(drop=True)
)
df3 = df1.copy()
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
另一种方法是用groupby+first
concat
:
pd.concat((df1,df2)).groupby('id').first().reset_index()
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
IIUC,
我们可以按id
设置索引并首先使用组合:
new_df = df1.set_index('id').combine_first(df2.set_index('id'))
print(new_df)
match
id
1 hello
2 there
3 put
4 stack
5 new
6 overflow
7 data
8 hi
9 NaN
使用地图。
如果您只是填充 NaN 值,则可以跨公共键使用map
。
df1["match"] = df1["match"].fillna(df1["id"].map(df2.set_index("id")["match"]))
print(df1)
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
您可以使用DataFrame.merge
+DataFrame.fillna
df1[['id']].merge(df2,on = 'id',how = 'left').fillna({'match':df1['match']})
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
看起来你想要combine_first,假设索引中的所有内容都正确排序。
df1.combine_first(df2)
如果没有,那么您需要合并索引df1.set_index('id').combine_first(df2.set_index('id'))
id match
0 1 hello
1 2 there
2 3 put
3 4 stack
4 5 new
5 6 overflow
6 7 data
7 8 hi
8 9 NaN
你也可以使用update
:
df1 = df1.set_index('id')
df2 = df2.set_index('id')
df1.update(df2)
df1
输出:
match
id
1 hello
2 there
3 put
4 stack
5 new
6 overflow
7 data
8 hi
9 NaN
df1.update(df2, join='left')
使用另一个数据帧中的非 NA 值就地修改。 在索引上对齐。没有返回值。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.update.html#pandas.DataFrame.update
哦,我的错,我没有重新加载看到斯科特的答案