【问题标题】:using pandas.cut() and setting it as the index of a dataframe使用 pandas.cut() 并将其设置为数据框的索引
【发布时间】:2018-01-25 01:30:33
【问题描述】:

我正在尝试找到一种更简单的方法来使用我的数据框运行聚合函数,而不是手动提取数据并将函数与数据框本身分开运行。我有一支球队的足球统计数据,我想根据年龄进行分析和统计。我想对年龄进行分类,然后根据这些年龄组运行统计数据。更具体地说,我有一个 df:

df = pd.DataFrame({'Age':[20,30,22,27,35,33,22,28,29,21,28,33,29,27,31,20,25,26,31,33,29,18],
             'Goals':np.random.randint(1,6,22),
             'Shots on Goals':np.random.randint(5,20,22),
             'Yellow Cards':np.random.randint(1,6,22),
             'Assists':np.random.randint(0,16,22)})
df['Age Grps'] = pd.cut(df.Age, bins =[17,24,28,32,36])
df.set_index(['Age Grps'], inplace = True)
df.head(8)

输出以下数据框,并将索引设置为分箱年龄组:

| Age Grps | Age | Assists | Goals | Shot on Goals | Yellow Cards |
|----------|-----|---------|-------|---------------|--------------|
|  (17,24] |  20 |    3    |   3   |       13      |       2      |
| (28, 32] |  30 |    2    |   3   |       11      |       3      |
|  (17,24] |  22 |    10   |   3   |       14      |       5      |
|  (24,28] |  27 |    3    |   1   |       16      |       3      |
|  (32,36] |  35 |    1    |   4   |       5       |       1      |
|  (32,36] |  33 |    5    |   4   |       17      |       1      |
|  (17,24] |  22 |    14   |   5   |       13      |       3      |
|  (24,28] |  28 |    14   |   2   |       7       |       4      |

是否可以按当前索引(Age Grps)进行分组以产生以下结果:

╔══════════╦═════╦═════════╦═══════╦═══════════════╦══════════════╗
║ Age Grps ║ Age ║ Assists ║ Goals ║ Shot on Goals ║ Yellow Cards ║
╠══════════╬═════╬═════════╬═══════╬═══════════════╬══════════════╣
║  (17,24] ║  20 ║    3    ║   3   ║       13      ║       2      ║
║          ╠═════╬═════════╬═══════╬═══════════════╬══════════════╣
║          ║  22 ║    14   ║   5   ║       13      ║       3      ║
║          ╠═════╬═════════╬═══════╬═══════════════╬══════════════╣
║          ║  22 ║    10   ║   3   ║       14      ║       5      ║
╠══════════╬═════╬═════════╬═══════╬═══════════════╬══════════════╣
║  (24,28] ║  27 ║    3    ║   1   ║       16      ║       3      ║
║          ╠═════╬═════════╬═══════╬═══════════════╬══════════════╣
║          ║  28 ║    14   ║   2   ║       7       ║       4      ║
╠══════════╬═════╬═════════╬═══════╬═══════════════╬══════════════╣
║  (28,32] ║  28 ║    14   ║   2   ║       7       ║       4      ║
╠══════════╬═════╬═════════╬═══════╬═══════════════╬══════════════╣
║  (32,36] ║  35 ║    1    ║   4   ║       5       ║       1      ║
║          ╠═════╬═════════╬═══════╬═══════════════╬══════════════╣
║          ║  33 ║    5    ║   4   ║       17      ║       4      ║
╚══════════╩═════╩═════════╩═══════╩═══════════════╩══════════════╝

我想要做的是运行每个年龄段的汇总统计数据,例如每个年龄段的平均助攻数、平均进球数、平均射门数等。例如:

df['Average Goals'] = df.groupby('bucket')['Goals'].mean()
df['Average Assists'] = df.groupby('bucket')['Assists'].mean()

为了生成这样的表:

╔══════════╦═════╦═════════╦═════════════════╦═══════╦═══════════════╦═══════════════╦══════════════╗
║ Index    ║ Age ║ Assists ║ Average Assists ║ Goals ║ Average Goals ║ Shot on Goals ║ Yellow Cards ║
╠══════════╬═════╬═════════╬═════════════════╬═══════╬═══════════════╬═══════════════╬══════════════╣
║  (17,24] ║  20 ║    3    ║        9        ║   3   ║      3.67     ║       13      ║       2      ║
║          ╠═════╬═════════╣                 ╬═══════╬               ╬═══════════════╬══════════════╣
║          ║  22 ║    14   ║                 ║   5   ║               ║       13      ║       3      ║
║          ╠═════╬═════════╣                 ╬═══════╬               ╬═══════════════╬══════════════╣
║          ║  22 ║    10   ║                 ║   3   ║               ║       14      ║       5      ║
╠══════════╬═════╬═════════╬═════════════════╬═══════╬═══════════════╬═══════════════╬══════════════╣
║  (24,28] ║  27 ║    3    ║       8.5       ║   1   ║      1.5      ║       16      ║       3      ║
║          ╠═════╬═════════╣                 ╬═══════╬               ╬═══════════════╬══════════════╣
║          ║  28 ║    14   ║                 ║   2   ║               ║       7       ║       4      ║ 
╠══════════╬═════╬═════════╬═════════════════╬═══════╬═══════════════╬═══════════════╬══════════════╣
║  (28,32] ║  28 ║    14   ║        14       ║   2   ║       2       ║       7       ║       4      ║
╠══════════╬═════╬═════════╬═════════════════╬═══════╬═══════════════╬═══════════════╬══════════════╣
║  (32,36] ║  35 ║    1    ║        3        ║   4   ║       4       ║       5       ║       1      ║
║          ╠═════╬═════════╣                 ╬═══════╬               ╬═══════════════╬══════════════╣
║          ║  33 ║    5    ║                 ║   4   ║               ║       17      ║       4      ║
╚══════════╩═════╩═════════╩═════════════════╩═══════╩═══════════════╩═══════════════╩══════════════╝

我知道我可以以列表的形式提取数据并执行我需要的统计数据,但我正试图以一种“pandorable”的方式做事。此外,我将使用 matplotlib 绘制这些数据,并且我想使用 pandas 和 matplotlib API df.plot() 的简单方法。

提前感谢您的帮助

【问题讨论】:

    标签: python pandas numpy matplotlib pandas-groupby


    【解决方案1】:

    如果需要新列到原始df,我认为你想要transform,但如果从列Age Grps 设置索引,它会返回很多警告:

    df['Age Grps'] = pd.cut(df.Age, bins =[17,24,28,32,36])
    df = df.sort_values('Age Grps')
    df['Average Goals'] = df.groupby('Age Grps')['Goals'].transform('mean')
    df['Average Assists'] = df.groupby('Age Grps')['Assists'].transform('mean')
    

    但是如果需要聚合数据使用DataFrameGroupBy.agg:

    df1 = df.groupby(pd.cut(df.Age, bins =[17,24,28,32,36]))
            .agg({'Goals':'mean', 'Assists':'mean', 'Yellow Cards':'sum'})
    print (df1)
              Yellow Cards    Assists     Goals
    Age                                        
    (17, 24]            12   8.000000  3.166667
    (24, 28]            18   4.833333  1.833333
    (28, 32]            21  11.333333  3.000000
    (32, 36]            13  11.000000  2.250000
    

    【讨论】:

    • 这部分给出了我正在寻找的答案。我想用你给我的这个提示自己尝试更多的事情,然后再回来详细说明这会导致什么。感谢您为我指明正确的方向
    • 如果我的回答对您有帮助,请不要忘记accept 它 - 单击答案旁边的复选标记 () 将其从灰色切换为已填充。谢谢。跨度>
    • 完美,我可以使用您上面提到的内容,我只是想避免对每一列都执行类似 avg_goals = list(df.Goals).mean() 之类的操作,因为我拥有的远不止这些上面列出的,那将是解决这个问题的一种非常费力的方法。再次感谢
    • 我不确定是否理解。你需要out = df.mean() 来表示所有数字列的平均值吗?
    • 不,我的第三个数据框如上所示,正是我想要完成的。我基本上是在尝试对 3 支不同的足球队(联赛冠军、联赛中队和联赛末位球队)进行分析,并确定球员年龄之间是否存在相关性球队和球队在联赛中的排名。这就是为什么我按年龄分组。然后我想比较三支球队中这些年龄组的某些统计数据。
    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 2021-12-31
    • 2021-06-01
    • 2017-05-31
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多