我一直在尝试为以下代码找到一个替代方案(可能更优雅(,但没有任何运气。这是我的代码:
import os
import pandas as pd
os.chdir(os.getcwd())
df1 = pd.DataFrame({'Month': [1]*6 + [13]*6,
'Temp': [0, 1, 2, 3, 4, 5]*2,
'Place': [12, 53, 6, 11, 9, 10, 0, 0, 0, 0, 0, 0],
'Place2': [1, 0, 23, 14, 9, 8, 0, 0, 0, 0, 0, 0],
'Place3': [2, 64, 24, 66, 14, 21, 0, 0, 0, 0, 0, 0]}
)
df2 = pd.DataFrame({'Month': [13] * 6,
'Temp': [0, 1, 2, 3, 4, 5],
'Place': [1, 22, 333, 444, 55, 6]})
# Here it creates new columns "Place_y" and "Place_x".
# I want to avoid this if possible.
df_merge = pd.merge(df1, df2, how='left',
left_on=['Temp', 'Month'],
right_on=['Temp', 'Month'])
df_merge.fillna(0, inplace=True)
add_not_nan = lambda x: x['Place_x'] if pd.isnull(x['Place_y']) else x['Place_y']
df_merge['Place'] = df_merge.apply(add_not_nan, axis=1)
df_merge.drop(['Place_x', 'Place_y'], axis=1, inplace=True)
print(df_merge)
我试图实现的是基于";月份";以及";温度";列,同时保留缺失值的0。我想知道是否有任何方法可以合并数据帧而不创建_x和_y列(基本上是跳过创建和删除这些列的方法(。
输入:
- 第一个数据帧
Month Temp Place Place2 Place3
0 1 0 12 1 2
1 1 1 53 0 64
2 1 2 6 23 24
3 1 3 11 14 66
4 1 4 9 9 14
5 1 5 10 8 21
6 13 0 0 0 0
7 13 1 0 0 0
8 13 2 0 0 0
9 13 3 0 0 0
10 13 4 0 0 0
11 13 5 0 0 0
- 第二个数据帧
Month Temp Place
0 13 0 1
1 13 1 22
2 13 2 333
3 13 3 444
4 13 4 55
5 13 5 6
输出:
- 合并后
Month Temp Place_x Place2 Place3 Place_y
0 1 0 12 1 2 NaN
1 1 1 53 0 64 NaN
2 1 2 6 23 24 NaN
3 1 3 11 14 66 NaN
4 1 4 9 9 14 NaN
5 1 5 10 8 21 NaN
6 13 0 0 0 0 1.0
7 13 1 0 0 0 22.0
8 13 2 0 0 0 333.0
9 13 3 0 0 0 444.0
10 13 4 0 0 0 55.0
11 13 5 0 0 0 6.0
- 决赛(需要(
Month Temp Place2 Place3 Place
0 1 0 1 2 0.0
1 1 1 0 64 0.0
2 1 2 23 24 0.0
3 1 3 14 66 0.0
4 1 4 9 14 0.0
5 1 5 8 21 0.0
6 13 0 0 0 1.0
7 13 1 0 0 22.0
8 13 2 0 0 333.0
9 13 3 0 0 444.0
10 13 4 0 0 55.0
11 13 5 0 0 6.0
似乎不需要df1
中的Place
列,您可以在合并前将其删除:
(df1.drop('Place', axis=1)
.merge(df2, how='left', on=['Temp', 'Month'])
.fillna({'Place': 0}))
# Month Temp Place2 Place3 Place
#0 1 0 1 2 0.0
#1 1 1 0 64 0.0
#2 1 2 23 24 0.0
#3 1 3 14 66 0.0
#4 1 4 9 14 0.0
#5 1 5 8 21 0.0
#6 13 0 0 0 1.0
#7 13 1 0 0 22.0
#8 13 2 0 0 333.0
#9 13 3 0 0 444.0
#10 13 4 0 0 55.0
#11 13 5 0 0 6.0
如果您不知道有多少这样的列,并且如果您总是想将第二个数据帧中的列包括在内,以用于未用作键列的重叠列名,那么您可以使用pd.merge
的后缀参数屏蔽这些变量,然后使用pandas.DataFrame.filter
:过滤掉带有屏蔽字符的列
df1.merge(df2,
how='left',
left_on=['Temp', 'Month'],
right_on=['Temp', 'Month'],
suffixes=('##@', '')).fillna(0).filter(regex='.*(?<!##@)$')
输出:
Month Temp Place2 Place3 Place
0 1 0 1 2 0.0
1 1 1 0 64 0.0
2 1 2 23 24 0.0
3 1 3 14 66 0.0
4 1 4 9 14 0.0
5 1 5 8 21 0.0
6 13 0 0 0 1.0
7 13 1 0 0 22.0
8 13 2 0 0 333.0
9 13 3 0 0 444.0
10 13 4 0 0 55.0
11 13 5 0 0 6.0
显然,您还可以在合并前通过检查第一个数据帧中第二个数据帧的列的存在来过滤掉这些列:
cols=[col for col in df1.columns if col in ('Temp', 'Month') or col not in df2.columns ]
df1[cols].merge(df2, how='left',
left_on=['Temp', 'Month'],
right_on=['Temp', 'Month']).fillna(0)
Month Temp Place2 Place3 Place
0 1 0 1 2 0.0
1 1 1 0 64 0.0
2 1 2 23 24 0.0
3 1 3 14 66 0.0
4 1 4 9 14 0.0
5 1 5 8 21 0.0
6 13 0 0 0 1.0
7 13 1 0 0 22.0
8 13 2 0 0 333.0
9 13 3 0 0 444.0
10 13 4 0 0 55.0
11 13 5 0 0 6.0