我有两个数据框:
df1 = pd.DataFrame({'player': ['AB','AB','AB'], 'contract_length':[2,3,1], 'year': [1998,2000,2003]})
df2 = pd.DataFrame({'player': ['AB','AB','AB','AB','AB','AB'], 'year':[1998,1999,2000,2001,2002,2003],'player_value': [4,3,7,10,9,2]})
df1
player contract_length year
0 AB 2 1998
1 AB 3 2000
2 AB 1 2003
df2
player year player_value
0 AB 1998 4
1 AB 1999 3
2 AB 2000 7
3 AB 2001 10
4 AB 2002 9
5 AB 2003 2
第一个数据框列出了玩家已签订的合同。例如:1998年,他签订了为期2年的合同。
第二个数据框列出了各个季节以及我为每个季节设置的值。
我正在尝试在df1上添加新列,以根据合同年和合同期限将df2中的玩家总值相加。例如,df1的第一行是1998年和2年。因此,该值将是7,来自1998年和1999年(2年合同)的球员值4和3。
我似乎无法弄清楚为什么它没有返回正确的结果:
for i,row in df1.iterrows():
year_list = list(range(row['year'],((row['year'])+(row['contract_length']))))
player = row['player']
df = pd.DataFrame(columns=['player_value'])
for year in year_list:
player_value = df2.loc[(df2['player']==player) & (df2['year'] == year),['player_value']]
df1['contract_value'] = sum(df['player_value'])
此返回:
player contract_length year contract_value
0 AB 2 1998 0
1 AB 3 2000 0
2 AB 1 2003 0
何时应该:
player contract_length year contract_value
0 AB 2 1998 7
1 AB 3 2000 26
2 AB 1 2003 2
没有返回错误。只是最后一列中的零。
答案 0 :(得分:2)
使用合同期限获取每年的切片,然后求和palyer_value
。
import pandas as pd
df1 = pd.DataFrame({'player': ['AB','AB','AB'], 'contract_length':[2,3,1], 'year': [1998,2000,2003]})
df2 = pd.DataFrame({'player': ['AB','AB','AB','AB','AB','AB'], 'year':[1998,1999,2000,2001,2002,2003],'player_value': [4,3,7,10,9,2]})
data = []
for index, row in df1.iterrows():
contract_data = df2[(df2['year'] >= row['year']) & (df2['year'] <= row['year']+row['contract_length']-1)]
sum = contract_data['player_value'].sum()
data.append(sum)
df1['contract_value'] = data
输出:
player contract_length year contract_value
0 AB 2 1998 7
1 AB 3 2000 26
2 AB 1 2003 2
答案 1 :(得分:1)
根据contract_length
考虑repeating
数据帧,然后assigning
另一列adds
基于组的年份,然后与第二列合并:
final = (df1.loc[df1.index.repeat(df1['contract_length'])]
.assign(year1 = lambda x: x['year']+x.groupby('year').cumcount())
.merge(df2, left_on = ['player','year1'],right_on = ['player','year']
,suffixes = ('','_y')).groupby(['player','contract_length','year']
,sort=False,as_index=False)['player_value'].sum())
player contract_length year player_value
0 AB 2 1998 7
1 AB 3 2000 26
2 AB 1 2003 2
将其分解为2个步骤:
m = df1.loc[df1.index.repeat(df1['contract_length'])].assign(year1 = lambda x:
x['year']+x.groupby('year').cumcount())
final1 = (m.merge(df2,left_on = ['player','year1'],right_on=['player','year']
,suffixes=('','_y').groupby(['player','contract_length','year']
,sort=False,as_index=False)['player_value'].sum())
player contract_length year player_value
0 AB 2 1998 7
1 AB 3 2000 26
2 AB 1 2003 2
就这样,您就知道我们正在将第二个数据框与以下内容合并:
print(m)
player contract_length year year1
0 AB 2 1998 1998
0 AB 2 1998 1999
1 AB 3 2000 2000
1 AB 3 2000 2001
1 AB 3 2000 2002
2 AB 1 2003 2003
答案 2 :(得分:0)
另一种尝试,使用.explode()
:
df1['contract_value'] = pd.merge(
df1.assign(years=df1.apply(lambda x: [*range(x['year'], x['year'] + x['contract_length'])] ,axis=1)).explode('years'),
df2, left_on=['player', 'years'], right_on=['player', 'year']
).groupby(['player', 'year_x'], as_index=False)['player_value'].sum()['player_value']
print(df1)
打印:
player contract_length year contract_value
0 AB 2 1998 7
1 AB 3 2000 26
2 AB 1 2003 2