如何在 Pandas 的一行中收集重复的数据行?

Ber*_*kay 1 python dataframe pandas data-science

我有一个数据集,其中包含 NBA 球员每场比赛的平均统计数据。一些球员的统计数据是重复的,因为他们本赛季曾在不同的球队。例如:

      Player       Pos  Age Tm    G     GS   MP      FG
8   Jarrett Allen   C   22  TOT  28     10  26.2     4.4
9   Jarrett Allen   C   22  BRK  12     5   26.7     3.7
10  Jarrett Allen   C   22  CLE  16     5   25.9     4.9
Run Code Online (Sandbox Code Playgroud)

我想平均 Jarrett Allen 的统计数据并将它们放在一行中。我怎样才能做到这一点?提前致谢。

S2L*_*S2L 10

x = [['a', 12, 5],['a', 12, 7], ['b', 15, 10],['b', 15, 12],['c', 20, 1]]

import pandas as pd
df = pd.DataFrame(x, columns=['name', 'age', 'score'])
print(df)
print('-----------')

df2 = df.groupby(['name', 'age']).mean()
print(df2)
Run Code Online (Sandbox Code Playgroud)

输出:

  name  age  score
0    a   12      5
1    a   12      7
2    b   15     10
3    b   15     12
4    c   20      1
-----------
          score
name age       
a    12       6
b    15      11
c    20       1
Run Code Online (Sandbox Code Playgroud)


moz*_*way 9

您可以groupby并使用agg来获得平均值。对于非数字列,我们取第一个值:

df.groupby('Player').agg({k: 'mean' if v in ('int64', 'float64') else 'first'
                          for k,v in df.dtypes[1:].items()})
Run Code Online (Sandbox Code Playgroud)

输出:

              Pos  Age   Tm          G        GS         MP        FG
Player                                                               
Jarrett Allen   C   22  TOT  18.666667  6.666667  26.266667  4.333333
Run Code Online (Sandbox Code Playgroud)

注意。字典理解的内容:

{'Pos': 'first',
 'Age': 'mean',
 'Tm': 'first',
 'G': 'mean',
 'GS': 'mean',
 'MP': 'mean',
 'FG': 'mean'}
Run Code Online (Sandbox Code Playgroud)

  • `agg` 使用函数聚合值。在这里,我使用字典来告诉它每列要计算哪个聚合(平均值或第一个)。我在答案中添加了文档的链接。字典是使用列类型计算的。如果是数字(int/float),我们使用“mean”进行聚合,否则我们采用第一个值。如果您想了解更多详细信息,请告诉我。 (3认同)

Gon*_*ica 5

选项1

如果考虑OP在问题中共享的数据框,df以下将完成这项工作

df_new = df.groupby('Player').agg(lambda x: x.iloc[0] if pd.api.types.is_string_dtype(x.dtype) else x.mean())

[Out]:
              Pos   Age   Tm          G        GS         MP        FG
Player                                                                
Jarrett Allen   C  22.0  TOT  18.666667  6.666667  26.266667  4.333333
Run Code Online (Sandbox Code Playgroud)

这个使用:

让我们使用新的数据框 来测试它,其中列df2中有更多元素Player

import numpy as np

df2 = pd.DataFrame({'Player': ['John Collins', 'John Collins', 'John Collins', 'Trae Young', 'Trae Young', 'Clint Capela', 'Jarrett Allen', 'Jarrett Allen', 'Jarrett Allen'],
                    'Pos': ['PF', 'PF', 'PF', 'PG', 'PG', 'C', 'C', 'C', 'C'],
                    'Age': np.random.randint(0, 100, 9),
                    'Tm': ['ATL', 'ATL', 'ATL', 'ATL', 'ATL', 'ATL', 'TOT', 'BRK', 'CLE'],
                    'G': np.random.randint(0, 100, 9),
                    'GS': np.random.randint(0, 100, 9),
                    'MP': np.random.uniform(0, 100, 9),
                    'FG': np.random.uniform(0, 100, 9)})

[Out]:
          Player Pos  Age   Tm   G  GS         MP         FG
0   John Collins  PF   71  ATL  75  39  16.123225  77.949756
1   John Collins  PF   60  ATL  49  49  30.308092  24.788401
2   John Collins  PF   52  ATL  33  92  11.087317  58.488575
3     Trae Young  PG   72  ATL  20  91  62.862313  60.169282
4     Trae Young  PG   85  ATL  61  77  30.248551  85.169038
5   Clint Capela   C   73  ATL   5  67  45.817690  21.966777
6  Jarrett Allen   C   23  TOT  60  51  93.076624  34.160823
7  Jarrett Allen   C   12  BRK   2  77  74.318568  78.755869
8  Jarrett Allen   C   44  CLE  82  81   7.375631  40.930844
Run Code Online (Sandbox Code Playgroud)

如果在 上测试操作df2,将会得到以下结果

df_new2 = df2.groupby('Player').agg(lambda x: x.iloc[0] if pd.api.types.is_string_dtype(x.dtype) else x.mean())

[Out]:
              Pos        Age   Tm          G         GS         MP         FG
Player                                                                       
Clint Capela    C  95.000000  ATL  30.000000  98.000000  46.476398  17.987104
Jarrett Allen   C  60.000000  TOT  48.666667  19.333333  70.050540  33.572896
John Collins   PF  74.333333  ATL  50.333333  52.666667  78.181457  78.152235
Trae Young     PG  57.500000  ATL  44.500000  47.500000  46.602543  53.835455
Run Code Online (Sandbox Code Playgroud)

选项2

根据所需的输出,假设只想按玩家分组(独立于AgeTm),一种更简单的解决方案是仅分组并传递,.mean()如下所示

df_new3 = df.groupby('Player').mean()

[Out]:

                Age          G        GS         MP        FG
Player                                                       
Jarrett Allen  22.0  18.666667  6.666667  26.266667  4.333333
Run Code Online (Sandbox Code Playgroud)

注意事项

  • 先前操作的输出不会显示非数字列(除了玩家名称)。