按日期填写Pandas中的行,条件是行不存在

时间:2018-04-07 11:17:42

标签: python pandas

如果该行在下一个日期不存在,您如何从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 teamdate的最后一次观察的所有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])

获取球员名单。

2 个答案:

答案 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']