如果该行在下一个日期不存在,您如何从Pandas数据框中“复制”以前的行,并按日期对其进行索引。这是出于以下问题的原因。
问题
我的示例data
是
DATE | TEAM | PLAYER
-----+------+-------
0 | A | John
0 | A | Tom
0 | B | Chris
0 | B | Rob
1 | A | John
1 | A | George
1 | B | Chris
2 | A | Rob
我正在尝试构建对象X
,以便我可以执行类似
X.loc[date, team]
它将返回players
team
上date
的最后一次观察的所有X.loc[0, 'A'] = ['John', 'Tom']
X.loc[0, 'B'] = ['Chris', 'Rob']
X.loc[1, 'A'] = ['John', 'Tom', 'George']
X.loc[1, 'B'] = ['Chris', 'Rob']
X.loc[2, 'A'] = ['John', 'Tom', 'George', 'Rob']
X.loc[2, 'B'] = ['Chris']
。
现在要明确,我想要
data_filled
观
我的想法是,我可以“填写”此前日期未被观察到的玩家的价值。 DATE | TEAM | PLAYER | FILLED
-----+------+--------+-------
0 | A | John | 0
0 | A | Tom | 0
0 | B | Chris | 0
0 | B | Rob | 0
1 | A | John | 0
1 | A | George| 0
1 | B | Chris | 0
1 | A | Tom | 1
1 | B | Rob | 1
2 | A | Rob | 0
2 | A | John | 1
2 | A | George| 1
2 | B | Chris | 1
2 | A | Tom | 1
FILLED
我在其中添加了data
列,以表示该行是否已添加到X = data_filled.set_index(['DATE', 'TEAM'])
。现在我相信我能得到我想要的东西
X.loc[data, team]
我可以使用
from matplotlib import pyplot as plt
plt.axis([0, 10, 0, 20])
获取球员名单。
答案 0 :(得分:1)
返回所有最后一次观察球队的球员。
而不是构建数据框以使用DataFrame.loc
,您可以定义自定义loc
函数
给定日期n
,我们可以使用以下所有玩家获得最后一支球队:
last_team = df[df.DATE<=n].groupby('PLAYER').TEAM.agg('last')
然后我们可以选择特定球队的球员
last_team.index[last_team.TEAM=='A'].values
根据需要在函数调用中组合上述两个步骤。
def myloc(frame, date, team):
last_team = frame[frame['DATE']<=date].groupby('PLAYER')['TEAM'].agg('last')
return last_team.index[last_team == team].values
示例输出:
In [11]: myloc(df, 0, 'A')
Out[10]: array(['John', 'Tom'], dtype=object)
In [11]: myloc(df, 1, 'A')
Out[11]: array(['George', 'John', 'Tom'], dtype=object)
In [12]: myloc(df, 2, 'A')
Out[12]: array(['George', 'John', 'Rob', 'Tom'], dtype=object)
In [13]: myloc(df, 0, 'B')
Out[13]: array(['Chris', 'Rob'], dtype=object)
In [14]: myloc(df, 1, 'B')
Out[14]: array(['Chris', 'Rob'], dtype=object)
In [15]: myloc(df, 2, 'B')
Out[15]: array(['Chris'], dtype=object)
性能更高的方法是使用pd.merge_asof构建一个玩家表格及其在指定日期的最新团队成员资格。
首先,我们必须建立一个包含所有可能球员的表格。日期。
df2 = pd.DataFrame(index=pd.MultiIndex.from_product([df.DATE.unique(), df.PLAYER.unique()])).reset_index()
df2.columns = ['DATE', 'PLAYER']
df3 = pd.merge_asof(df2, df, on='DATE', by='PLAYER').set_index(['DATE', 'TEAM']).sort_index()
df3
# outputs
PLAYER
DATE TEAM
0 A John
A Tom
B Chris
B Rob
NaN George
1 A John
A Tom
A George
B Chris
B Rob
2 A John
A Tom
A Rob
A George
B Chris
然后你可以使用loc
让最后被观察的球员为球队效力
df3.loc[0, 'A'].PLAYER.values
# outputs: array(['John', 'Tom'], dtype=object)
答案 1 :(得分:1)
这种方法可以将每位玩家最后一支已知的球队向前填充到未来的日期中。我创建了中间变量以避免巨大的单行。
ffilled = df.set_index(['PLAYER', 'DATE']).unstack().ffill(axis=1)
tidy = ffilled.stack().reset_index()
result = tidy.set_index(['DATE', 'TEAM']).sort_index()
result
PLAYER
DATE TEAM
0 A John
A Tom
B Chris
B Rob
1 A George
A John
A Tom
B Chris
B Rob
2 A George
A John
A Rob
A Tom
B Chris
result.loc[1, 'A']
PLAYER
DATE TEAM
1 A George
A John
A Tom
result.loc[1, 'A'].values.flatten().tolist()
['George', 'John', 'Tom']