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

2024-04-26 17:39:23 发布

您现在位置:Python中文网/ 问答频道 /正文

如果下一个日期不存在前一行,如何从按日期索引的数据帧中“复制”前一行。这是由下面的问题引起的。你知道吗

问题

我的例子是

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]

得到球员名单。你知道吗


Tags: 数据datadatejohnlocteamchrisplayer
2条回答

return all players whose last observation was for team on date.

您可以定义一个自定义的loc函数,而不是构造一个数据帧来使用DataFrame.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.合并在给定的日期建立一个球员和他们最近的球队成员表。你知道吗

首先,我们必须建立一个包含所有可能参与者和日期的表格。你知道吗

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)

这种方法将每个球员的最后一个已知团队填充到未来的日期中。我创建中间变量来避免一个大的单行程序。你知道吗

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

相关问题 更多 >