使用.groupby(…).agg(sum)创建新的Pandas.DataFrame,然后恢复未推荐的列

2024-06-09 20:56:05 发布

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

我从baseabll seasons的一个数据帧开始,其中一部分看起来类似于:

                   Name  Season   AB    H  SB  playerid
13047   A.J. Pierzynski    2013  503  137   1       746
6891    A.J. Pierzynski    2006  509  150   1       746
1374          Rod Carew    1977  616  239  23   1001942
1422        Stan Musial    1948  611  230   7   1009405
1507        Todd Helton    2000  580  216   5       432
1508  Nomar Garciaparra    2000  529  197   5       190
1509      Ichiro Suzuki    2004  704  262  36      1101

从这些赛季开始,我想创建一个职业统计数据框架;也就是说,每个玩家有一行,这是他们的AB、H等的总和。这个数据框仍然应该包括玩家的名字。上面的playerid是每个玩家的唯一键,在创建职业统计数据框架后,它应该是一个索引或列中的一个不变值

我假设的起点是df_careers = df_seasons.groupby('playerid').agg(sum),但这忽略了所有非数字数据。有了numeric_only = False我可以从连接中得到一些混乱的名称列,比如'Ichiro SuzukiIchiro SuzukiIchiro SuzukiIchiro Suzuki',但这只需要一系列的清理。这是我希望能够处理其他数据集的事情,而我拥有的实际数据更像是25列,因此我宁愿理解一个从一开始就获取或保存名称数据的特定例程,而不是编写一个特定函数并使用groupby('playerid').agg(func)(或类似过程)来完成(如果可能的话)

我猜有一个相当简单的方法可以做到这一点,但我一周前才开始学习熊猫,所以我的知识还存在差距


Tags: 数据框架dfab玩家agg统计数据groupby
3条回答

您可以编写自己的条件“如何包含非求和列”

col = df.columns.tolist()
col.remove('playerid')
df.groupby('playerid').agg({i : lambda x: x.iloc[0] if x.dtypes=='object' else x.sum() for i in df.columns})

df:

           Name                 Season  AB   H      SB  playerid
playerid                        
190        Nomar_Garciaparra    2000    529  197    5   190
432        Todd_Helton          2000    580  216    5   432
746        A.J._Pierzynski      4019    1012 287    2   1492
1101       Ichiro_Suzuki        2004    704  262    36  1101
1001942    Rod_Carew            1977    616  239    23  1001942
1009405    Stan_Musial          1948    611  230    7   1009405

如果“playerid”和“Name”之间存在一对一的关系,那么您可以在groupby列中包含“Name”:

stat_cols = ['AB', 'H', 'SB']
groupby_cols = ['playerid', 'Name']
results = df.groupby(groupby_cols)[stat_cols].sum()

结果:

                              AB    H  SB
playerid Name                            
190      Nomar Garciaparra   529  197   5
432      Todd Helton         580  216   5
746      A.J. Pierzynski    1012  287   2
1101     Ichiro Suzuki       704  262  36
1001942  Rod Carew           616  239  23
1009405  Stan Musial         611  230   7

如果您希望仅按“playerid”分组,然后再添加“Name”数据,则可以创建“playerid”到“Name”的映射作为字典,并使用map进行查找:

results = df.groupby('playerid')[stat_cols].sum()
name_map = pd.Series(df.Name.to_numpy(), df.playerid).to_dict()
results['Name'] = results.index.map(name_map)

结果:

            AB    H  SB               Name
playerid                                  
190        529  197   5  Nomar Garciaparra
432        580  216   5        Todd Helton
746       1012  287   2    A.J. Pierzynski
1101       704  262  36      Ichiro Suzuki
1001942    616  239  23          Rod Carew
1009405    611  230   7        Stan Musial

agg()可以接受将列名映射到函数的字典。因此,一种解决方案是将字典传递给agg,指定应用于每列的函数

使用上面的示例数据,可以使用

mapping = { 'AB': sum,'H': sum, 'SB': sum, 'Season': max, 'Name': max }
df_1 = df.groupby('playerid').agg(mapping)

对于那些不应该求和的,选择使用“max”是任意的。如果希望以某种方式处理列,可以定义lambda函数以应用于该列。DataFrameGroupBy.agg可以使用任何将使用DataFrame.apply的函数

要将其扩展到更大的数据集,可以使用字典理解。这将很有效:

dictionary = { x : sum for x in df.columns}
dont_sum = {'Name': max,  'Season': max}
dictionary.update(dont_sum)
df_1 = df.groupby('playerid').agg(dictionary)

相关问题 更多 >