在比较第一行与来自第二个DF的多行后,将DF中的每一行映射到另一个DF中的一行的最佳方法是什么? &g



我有两个dataframe,一个包含不同的日期和不同的player_id。第二个包含每个球员的评级历史,这意味着它包含不同的日期和不同的player_id和player_rating与一个唯一的id的每一行。

现在,我想通过比较两个DataFrame中的日期列,为第一个DataFrame添加一列,该列具有player_rating的一个值。

例如:

print(df_1)
date  player_id
0  2006          1
1  2006          2
2  2012          3
3  2008          2
4  2010          1
print(df_2)
date  player_id  player_rating
0  2005          1             50
1  2007          2             55
2  2005          3             70
3  2005          2             65
4  2009          1             60
5  2011          2             75
6  2011          3             85

在这里,我应该比较df_1中的第一行与df_2中的第一行和第五行(相同的player_id),然后从df_2中选择具有最新日期且小于df_1中的日期的行。因此,我应该选择第一行并将player_rating设置为50。

最后,我应该得到:
print(df_1)
date  player_id  player_rating
0  2006          1             50
1  2006          2             65
2  2012          3             85
3  2008          2             55
4  2010          1             60

我已经尝试了许多解决方案,并得到以下想法,但相对于一个庞大的数据集(大约一百万行df_1和+100k行df_2)运行需要很多时间:

def get_rating(date, player_id):
return df_2[(df_2['player_id']==player_id) & (df_2['date'] < date)].sort_values(by=['date'], ascending=False).player_rating.iloc[0]
df_1['player_rating'] = [get_rating(x,y) for x, y in zip(df_1['date'], df_1['player_id'])]

有没有更好的方法来节省时间呢?提前谢谢你。

您可能需要测试效率:

(df1.merge(df2, on='player_id', how = 'left', suffixes=(None, '_y'))
.sort_values(['date', 'date_y'])
.query('date > date_y')
.groupby(['date', 'player_id'])
.tail(1)
.drop(columns='date_y')
.sort_index()
)

date  player_id  player_rating
0   2006          1             50
3   2006          2             65
6   2012          3             85
7   2008          2             55
11  2010          1             60

您可以尝试合并player_id上的两个数据帧,然后使用有关日期的逻辑。

<标题>数据
import pandas as pd
df1 = pd.DataFrame(
{'date': {0: 2006, 1: 2006, 2: 2012, 3: 2008, 4: 2010},
'player_id': {0: 1, 1: 2, 2: 3, 3: 2, 4: 1}})
df2 =  pd.DataFrame(
{'date': {0: 2005, 1: 2007, 2: 2005, 3: 2005, 4: 2009, 5: 2011, 6: 2011},
'player_id': {0: 1, 1: 2, 2: 3, 3: 2, 4: 1, 5: 2, 6: 3},
'player_rating': {0: 50, 1: 55, 2: 70, 3: 65, 4: 60, 5: 75, 6: 85}})
<标题>合并
df = pd.merge(df1, df2, on=["player_id"])

数据看起来像

date_x  player_id  date_y  player_rating
0     2006          1    2005             50
1     2006          1    2009             60
2     2010          1    2005             50
3     2010          1    2009             60
4     2006          2    2007             55
5     2006          2    2005             65
6     2006          2    2011             75
7     2008          2    2007             55
8     2008          2    2005             65
9     2008          2    2011             75
10    2012          3    2005             70
11    2012          3    2011             85
<标题>过滤器h1> 在你要求date_x大于date_y
df = df[df["date_x"].gt(df["date_y"])].reset_index(drop=True)

还有


date_x  player_id  date_y  player_rating
0    2006          1    2005             50
1    2010          1    2005             50
2    2010          1    2009             60
3    2006          2    2005             65
4    2008          2    2007             55
5    2008          2    2005             65
6    2012          3    2005             70
7    2012          3    2011             85

使用groupby查找每年的最晚日期

这里我们寻找组中date_y大的索引

grp = df.groupby(["date_x", "player_id"])["date_y"].idxmax()
print(grp)
date_x  player_id
2006    1            0
2            3
2008    2            4
2010    1            2
2012    3            7
Name: date_y, dtype: int64

我们用这些索引

进行过滤
df = df[df.index.isin(grp.values)].reset_index(drop=True)

看起来像

date_x  player_id  date_y  player_rating
0    2006          1    2005             50
1    2010          1    2009             60
2    2006          2    2005             65
3    2008          2    2007             55
4    2012          3    2011             85

,我们删除列并重命名第一个。

df = df.drop(columns=["date_y"])
.rename(columns={"date_x":"date"})

返回


date  player_id  player_rating
0  2006          1             50
1  2010          1             60
2  2006          2             65
3  2008          2             55
4  2012          3             85

最新更新