我在Pandas中使用重叠列合并2个不同大小的DataFrame时遇到了一些麻烦。
df1 =
+-------+--------+--------+-------+
| value | method | number | price |
+-------+--------+--------+-------+
| 0.5 | add | 489245 | 600 |
| 0.7 | add | 489245 | NaN |
| 0.7 | mul | 584682 | 225 |
| 0.9 | mul | 624602 | NaN |
| 0.95 | mul | 624602 | NaN |
| 0.99 | mul | 624602 | NaN |
| NaN | NaN | 900000 | 300 |
| NaN | add | 900000 | NaN |
+-------+--------+--------+-------+
df2 =
+--------+-------+-----+-----+
| number | price | loc | get |
+--------+-------+-----+-----+
| 489245 | 200 | aa | up |
| 584682 | NaN | ab | NaN |
| 624602 | NaN | bb | NaN |
| 900000 | NaN | cc | dn |
+--------+-------+-----+-----+
我预期的结果:
+-------+--------+--------+-------+-----+-----+
| value | method | number | price | loc | get |
+-------+--------+--------+-------+-----+-----+
| 0.5 | add | 489245 | 200 | aa | up |
| 0.7 | add | 489245 | 200 | aa | up |
| 0.7 | mul | 584682 | 225 | ab | NaN |
| 0.9 | mul | 624602 | NaN | bb | NaN |
| 0.95 | mul | 624602 | NaN | bb | NaN |
| 0.99 | mul | 624602 | NaN | bb | NaN |
| NaN | NaN | 900000 | 300 | cc | dn |
| NaN | add | 900000 | NaN | cc | dn |
+-------+--------+--------+-------+-----+-----+
例如,要加入的列='数字'。如果df1和df2在重叠列上都具有非NaN值(如'price'),则df2将是优选的。否则,应该写一个非NaN的人。
答案 0 :(得分:3)
摘要:merge
后跟一些DataFrame操作,然后是update
。
首先加载数据(此处包含以供参考)。
In [1]: import pandas
In [2]: df1 = pandas.read_csv('df1.csv')
In [3]: df2 = pandas.read_csv('df2.csv')
In [4]: df1
Out[4]:
value method number price
0 0.50 add 489245 600
1 0.70 add 489245 NaN
2 0.70 mul 584682 225
3 0.90 mul 624602 NaN
4 0.95 mul 624602 NaN
5 0.99 mul 624602 NaN
6 NaN NaN 900000 300
7 NaN add 900000 NaN
8 NaN NaN NaN NaN
In [5]: df2
Out[5]:
number price loc get
0 489245 200 aa up
1 584682 NaN ab NaN
2 624602 NaN bb NaN
3 900000 NaN cc dn
接下来合并'number'
In [6]: mdf = pandas.merge(df1,df2,on='number')
In [7]: mdf
Out[7]:
value method number price_x price_y loc get
0 0.50 add 489245 600 200 aa up
1 0.70 add 489245 NaN 200 aa up
2 0.70 mul 584682 225 NaN ab NaN
3 0.90 mul 624602 NaN NaN bb NaN
4 0.95 mul 624602 NaN NaN bb NaN
5 0.99 mul 624602 NaN NaN bb NaN
6 NaN NaN 900000 300 NaN cc dn
7 NaN add 900000 NaN NaN cc dn
当显示相同的列时,pandas.merge
会将两者都放在合并的DataFrame中,并附加后缀。在这种情况下,我们希望使用'price_x'
更新'price_y'
并调用结果'price'
。为此,我们可以创建一个仅包含'price_y'
中数据的数据框,从合并的DataFrame中删除该列,并将价格列重命名为'price'
。
In [8]: pdf = mdf.price_y
In [9]: pdf = pandas.DataFrame(pdf)
In [10]: del mdf['price_y']
In [11]: mdf.rename(columns = {'price_x':'price'},inplace=True)
In [12]: pdf.rename(columns = {'price_y':'price'},inplace=True)
In [13]: mdf
Out[13]:
value method number price loc get
0 0.50 add 489245 600 aa up
1 0.70 add 489245 NaN aa up
2 0.70 mul 584682 225 ab NaN
3 0.90 mul 624602 NaN bb NaN
4 0.95 mul 624602 NaN bb NaN
5 0.99 mul 624602 NaN bb NaN
6 NaN NaN 900000 300 cc dn
7 NaN add 900000 NaN cc dn
In [14]: pdf
Out[14]:
price
0 200
1 200
2 NaN
3 NaN
4 NaN
5 NaN
6 NaN
7 NaN
现在我们可以使用.update
将pdf
中的任何非NaN值放入mdf
。
In [15]: mdf.update(pdf)
In [16]: mdf
Out[16]:
value method number price loc get
0 0.50 add 489245 200 aa up
1 0.70 add 489245 200 aa up
2 0.70 mul 584682 225 ab NaN
3 0.90 mul 624602 NaN bb NaN
4 0.95 mul 624602 NaN bb NaN
5 0.99 mul 624602 NaN bb NaN
6 NaN NaN 900000 300 cc dn
7 NaN add 900000 NaN cc dn
如果需要更复杂的规则选择值,请将mdf.update(pdf)
替换为mdf.combine(pdf, function_of_two_variables_returning_preferred_value)
。
答案 1 :(得分:2)
合并后可以使用numpy.where()
:
>>> df1 = pd.DataFrame({'number':[1,1,2,2,3], 'price':[600,np.NaN,225,np.NaN,np.NaN], 'method':['add','add','mul','mul','mul']})
>>> df2 = pd.DataFrame({'number':[1,2,3], 'price':[200,np.NaN,np.NaN], 'loc':['aa','bb','cc']})
>>> df3 = pd.merge(df1, df2, on='number', suffixes=['_1', ''])
>>> df3
method number price_1 loc price
0 add 1 600 aa 200
1 add 1 NaN aa 200
2 mul 2 225 bb NaN
3 mul 2 NaN bb NaN
4 mul 3 NaN cc NaN
>>> df3['price'] = np.where(df3['price'].isnull(), df3['price_1'], df3['price'])
>>> df3
method number price_1 loc price
0 add 1 600 aa 200
1 add 1 NaN aa 200
2 mul 2 225 bb 225
3 mul 2 NaN bb NaN
4 mul 3 NaN cc NaN
>>> del df3['price_1']
>>> df3
method number loc price
0 add 1 aa 200
1 add 1 aa 200
2 mul 2 bb 225
3 mul 2 bb NaN
4 mul 3 cc NaN
另一种方法是使用pandas.Series.fillna()
方法:
>>> df3['price'] = df3['price'].fillna(df3['price_1'])
>>> del df3['price_1']
>>> df3
method number loc price
0 add 1 aa 200
1 add 1 aa 200
2 mul 2 bb 225
3 mul 2 bb NaN
4 mul 3 cc NaN