如何在 Pandas 中使用 groupby 来计算列
How to use groupby in Pandas to compute columns
我有一个 table 基于未聚合的数据。我想使用 GroupBy "slice" 我的数据并计算每个场景的平均值。
比如dota中的一些英雄,因为它很好玩:
Bracket MatchID Duration Hero Radiant Win Kills Deaths Assists GPM XPM CS Denies Level HeroDMG
0 n 32966652 1523 Pugna True True 1 1 3 292 265 28 5 11 3056
1 n 32966652 1523 Lich True True 3 0 8 288 297 36 3 11 5115
2 n 32966652 1523 Lina True True 8 2 1 378 366 63 1 13 9537
3 n 32966652 1523 Kunkka True True 5 0 4 415 351 73 0 12 6239
4 n 32966652 1523 Bounty Hunter True True 1 0 2 465 362 131 4 13 1400
我想看看每个英雄在输赢时的平均 GPM 是多少,我还想看看它在括号("n"、"h" 或 "v" 表示 "Normal"、"High Skill" 或 "Very high skill").
因此我会 运行:
gpm = data.groupby(["Hero", "Bracket", "Win"]).mean()
得到这样的东西:
MatchID Duration Radiant Kills Deaths Assists GPM XPM CS Denies Level HeroDMG
Hero Bracket Win
Alchemist h False 30983107.993671 2302.712025 0.462025 2.639241 8.139241 8.379747 285.753165 365.015823 113.784810 4.310127 15.674051 6132.193038
True 30998808.981395 2499.879070 0.544186 5.265116 5.325581 15.195349 445.200000 521.162791 157.493023 4.855814 19.683721 9514.841860
n False 30438522.501672 2536.304348 0.494983 2.705686 8.103679 9.250836 254.806020 339.187291 98.311037 3.170569 15.829431 6201.595318
True 30305649.194805 2683.688312 0.476190 5.320346 5.502165 15.705628 391.030303 484.995671 133.926407 3.506494 19.705628 9246.168831
v False 28020985.500000 2142.162879 0.518939 2.670455 7.560606 7.613636 302.996212 372.867424 119.337121 5.696970 15.284091 6232.712121
True 28259817.386503 2415.957055 0.595092 5.171779 5.233129 15.018405 486.736196 546.564417 174.932515 7.245399 19.877301 10143.98773
现在,我想根据所有这些数字来定义炼金术士,让我们称它们为"Hero-related features"。我的 objective 是让每个英雄成为这个 space 特征中的一个数据点,因此我想要这样的东西:
Hero Kills_High_Win Kills_High_Loss Kills_Normal_Win Kills_Normal_Loss
Alchemist 5.265116 2.639241 5.320346 2.705686
table 中的所有功能依此类推。我还想根据这些场景自动生成列的名称——名称可以是任何名称,只要与实际组合相关(例如 "Bracket" == "n" 和 "Win" == "True").
要达到您想要的 table,您基本上只需拆开 gpm
即可将 Bracket 和 Win 移到列中:
unstacked = gpm.unstack(['Bracket', 'Win'])
然后您可以使用简单的 str.join
从列级别创建字符串:
new_cols = unstacked.columns.to_series().map(
lambda t: '_'.join(str(e) for e in t))
# The actual string values are in the right-most column
new_cols
Out[27]:
Bracket Win
MatchID n True MatchID_n_True
Duration n True Duration_n_True
Radiant n True Radiant_n_True
Kills n True Kills_n_True
Deaths n True Deaths_n_True
# etc.
并将这些设置为列:
unstacked.columns = new_cols
unstacked.iloc[:5, :5]
Out[31]:
MatchID_n_True Duration_n_True Radiant_n_True Kills_n_True Hero
Kunkka 32966652 1523 True 5
Lich 32966652 1523 True 3
Lina 32966652 1523 True 8
Pugna 32966652 1523 True 1
Deaths_n_True
Hero
Kunkka 0
Lich 0
Lina 2
Pugna 1
我有一个 table 基于未聚合的数据。我想使用 GroupBy "slice" 我的数据并计算每个场景的平均值。
比如dota中的一些英雄,因为它很好玩:
Bracket MatchID Duration Hero Radiant Win Kills Deaths Assists GPM XPM CS Denies Level HeroDMG
0 n 32966652 1523 Pugna True True 1 1 3 292 265 28 5 11 3056
1 n 32966652 1523 Lich True True 3 0 8 288 297 36 3 11 5115
2 n 32966652 1523 Lina True True 8 2 1 378 366 63 1 13 9537
3 n 32966652 1523 Kunkka True True 5 0 4 415 351 73 0 12 6239
4 n 32966652 1523 Bounty Hunter True True 1 0 2 465 362 131 4 13 1400
我想看看每个英雄在输赢时的平均 GPM 是多少,我还想看看它在括号("n"、"h" 或 "v" 表示 "Normal"、"High Skill" 或 "Very high skill").
因此我会 运行:
gpm = data.groupby(["Hero", "Bracket", "Win"]).mean()
得到这样的东西:
MatchID Duration Radiant Kills Deaths Assists GPM XPM CS Denies Level HeroDMG
Hero Bracket Win
Alchemist h False 30983107.993671 2302.712025 0.462025 2.639241 8.139241 8.379747 285.753165 365.015823 113.784810 4.310127 15.674051 6132.193038
True 30998808.981395 2499.879070 0.544186 5.265116 5.325581 15.195349 445.200000 521.162791 157.493023 4.855814 19.683721 9514.841860
n False 30438522.501672 2536.304348 0.494983 2.705686 8.103679 9.250836 254.806020 339.187291 98.311037 3.170569 15.829431 6201.595318
True 30305649.194805 2683.688312 0.476190 5.320346 5.502165 15.705628 391.030303 484.995671 133.926407 3.506494 19.705628 9246.168831
v False 28020985.500000 2142.162879 0.518939 2.670455 7.560606 7.613636 302.996212 372.867424 119.337121 5.696970 15.284091 6232.712121
True 28259817.386503 2415.957055 0.595092 5.171779 5.233129 15.018405 486.736196 546.564417 174.932515 7.245399 19.877301 10143.98773
现在,我想根据所有这些数字来定义炼金术士,让我们称它们为"Hero-related features"。我的 objective 是让每个英雄成为这个 space 特征中的一个数据点,因此我想要这样的东西:
Hero Kills_High_Win Kills_High_Loss Kills_Normal_Win Kills_Normal_Loss
Alchemist 5.265116 2.639241 5.320346 2.705686
table 中的所有功能依此类推。我还想根据这些场景自动生成列的名称——名称可以是任何名称,只要与实际组合相关(例如 "Bracket" == "n" 和 "Win" == "True").
要达到您想要的 table,您基本上只需拆开 gpm
即可将 Bracket 和 Win 移到列中:
unstacked = gpm.unstack(['Bracket', 'Win'])
然后您可以使用简单的 str.join
从列级别创建字符串:
new_cols = unstacked.columns.to_series().map(
lambda t: '_'.join(str(e) for e in t))
# The actual string values are in the right-most column
new_cols
Out[27]:
Bracket Win
MatchID n True MatchID_n_True
Duration n True Duration_n_True
Radiant n True Radiant_n_True
Kills n True Kills_n_True
Deaths n True Deaths_n_True
# etc.
并将这些设置为列:
unstacked.columns = new_cols
unstacked.iloc[:5, :5]
Out[31]:
MatchID_n_True Duration_n_True Radiant_n_True Kills_n_True Hero
Kunkka 32966652 1523 True 5
Lich 32966652 1523 True 3
Lina 32966652 1523 True 8
Pugna 32966652 1523 True 1
Deaths_n_True
Hero
Kunkka 0
Lich 0
Lina 2
Pugna 1