如何在pandas中正确添加多个系列?
How to add multiple series in pandas correctly?
我有一个问题。
在我的数据框中,我将(游戏玩家的)名字存储在四列 W1、W2、W3、W4 中,用于赢得一轮的四名玩家以及输掉一轮的 L1、L2、L3、L4。还有一列 WP 表示赢分(取决于所玩的地图)和 LP 表示输分,即 -WP。
这些将是所讨论的 10 列的 .head() 。索引是玩的回合。它基本上是 history/tracker 过去的游戏。
{'W1': {0: nan, 1: 'Matthi', 2: 'Vain', 3: 'Matthi', 4: 'Markus'},
'W2': {0: nan, 1: 'Paddy', 2: 'Marvin', 3: 'Jonas', 4: 'Marvin'},
'W3': {0: nan, 1: 'Max', 2: 'Paddy', 3: 'Vain', 4: 'Johann'},
'W4': {0: nan, 1: nan, 2: 'Max', 3: 'Johannes', 4: 'Max'},
'WP': {0: nan, 1: 5.0, 2: 5.0, 3: 3.0, 4: 4.0},
'L1': {0: nan, 1: 'Timi', 2: 'Matthi', 3: 'Timi', 4: 'Matthi'},
'L2': {0: nan, 1: 'Markus', 2: 'Timi', 3: 'Markus', 4: 'Timi'},
'L3': {0: nan, 1: 'Marvin', 2: 'Markus', 3: 'Marvin', 4: 'Vain'},
'L4': {0: nan, 1: nan, 2: 'Johannes', 3: 'Nille', 4: 'Paddy'},
'LP': {0: nan, 1: -5.0, 2: -5.0, 3: -3.0, 4: -4.0}}
我想做的是进行排名,例如,对于“Max”,每次他在任一获胜玩家列中时都添加 WP,并在每次他在任一失败者列中减去 LP玩家专栏。
我希望我能做到这一点:
df.groupby("W1")["WP"].sum()+ df.groupby("W2")["WP"].sum()+ df.groupby("W3")["WP"].sum()+ df.groupby("W4")["WP"].sum()+ df.groupby("L1")["LP"].sum()+ df.groupby("L2")["LP"].sum()+ df.groupby("L3")["LP"].sum()+ df.groupby("L4")["LP"].sum()
但这给了我(很多“不应该”存在的 NaN,这当然是整个 df):
Funkey NaN
Johann NaN
Johannes -16.0
Jonas 22.0
Markus NaN
Marvin 41.0
Matthi NaN
Max 38.0
Nille NaN
Paddy -2.0
Timi NaN
Vain -16.0
dtype: float64
奇怪的是(对我来说)所有不是 NaN 的值都是正确的。
现在,我认为问题在于四列中的名称有些随机。这也意味着并非每一列都具有所有名称。例如。 “Max”有时会出现在W1,有时会出现在W2,但可能永远不会出现在W3或W4。
我还认为我可以用:
pd.Series.add(df.groupby("W1")["WP"].sum(), df.groupby("W2")["WP"].sum(), etc., fill_value=0)
但是,如果我放置三个以上的 groupby,就会出现错误。
我怎样才能实现我想做的事情?
您可以使用 melt
来展平数据框并计算每个玩家的分数。
df1 = df.melt(['WP', 'LP'], var_name='W/L', value_name='Player').dropna()
df1['Points'] = np.where(df1['W/L'].str[0] == 'W', df1['WP'], df1['LP'])
out = df1.groupby('Player', as_index=False)['Points'].sum() \
.sort_values('Points', ascending=False, ignore_index=True)
输出
Player
Points
Max
14
Paddy
6
Johann
4
Vain
4
Jonas
3
Marvin
1
Matthi
-1
Johannes
-2
Nille
-3
Markus
-9
Timi
-17
检查 df1
以查看中间数据帧。
IIUC,melt
重塑,根据列名计算点(如果以 W
开头),以及 grouby
+sum
:
import numpy as np
(df
.melt(id_vars=['WP','LP'], value_name='name')
.assign(points=lambda d: np.where(d['variable'].str.startswith('W'), d['WP'], d['LP']))
.groupby('name')['points'].sum()
)
输出:
name
Johann 4.0
Johannes -2.0
Jonas 3.0
Markus -9.0
Marvin 1.0
Matthi -1.0
Max 14.0
Nille -3.0
Paddy 6.0
Timi -17.0
Vain 4.0
Name: points, dtype: float64
我有一个问题。 在我的数据框中,我将(游戏玩家的)名字存储在四列 W1、W2、W3、W4 中,用于赢得一轮的四名玩家以及输掉一轮的 L1、L2、L3、L4。还有一列 WP 表示赢分(取决于所玩的地图)和 LP 表示输分,即 -WP。 这些将是所讨论的 10 列的 .head() 。索引是玩的回合。它基本上是 history/tracker 过去的游戏。
{'W1': {0: nan, 1: 'Matthi', 2: 'Vain', 3: 'Matthi', 4: 'Markus'},
'W2': {0: nan, 1: 'Paddy', 2: 'Marvin', 3: 'Jonas', 4: 'Marvin'},
'W3': {0: nan, 1: 'Max', 2: 'Paddy', 3: 'Vain', 4: 'Johann'},
'W4': {0: nan, 1: nan, 2: 'Max', 3: 'Johannes', 4: 'Max'},
'WP': {0: nan, 1: 5.0, 2: 5.0, 3: 3.0, 4: 4.0},
'L1': {0: nan, 1: 'Timi', 2: 'Matthi', 3: 'Timi', 4: 'Matthi'},
'L2': {0: nan, 1: 'Markus', 2: 'Timi', 3: 'Markus', 4: 'Timi'},
'L3': {0: nan, 1: 'Marvin', 2: 'Markus', 3: 'Marvin', 4: 'Vain'},
'L4': {0: nan, 1: nan, 2: 'Johannes', 3: 'Nille', 4: 'Paddy'},
'LP': {0: nan, 1: -5.0, 2: -5.0, 3: -3.0, 4: -4.0}}
我想做的是进行排名,例如,对于“Max”,每次他在任一获胜玩家列中时都添加 WP,并在每次他在任一失败者列中减去 LP玩家专栏。
我希望我能做到这一点:
df.groupby("W1")["WP"].sum()+ df.groupby("W2")["WP"].sum()+ df.groupby("W3")["WP"].sum()+ df.groupby("W4")["WP"].sum()+ df.groupby("L1")["LP"].sum()+ df.groupby("L2")["LP"].sum()+ df.groupby("L3")["LP"].sum()+ df.groupby("L4")["LP"].sum()
但这给了我(很多“不应该”存在的 NaN,这当然是整个 df):
Funkey NaN
Johann NaN
Johannes -16.0
Jonas 22.0
Markus NaN
Marvin 41.0
Matthi NaN
Max 38.0
Nille NaN
Paddy -2.0
Timi NaN
Vain -16.0
dtype: float64
奇怪的是(对我来说)所有不是 NaN 的值都是正确的。
现在,我认为问题在于四列中的名称有些随机。这也意味着并非每一列都具有所有名称。例如。 “Max”有时会出现在W1,有时会出现在W2,但可能永远不会出现在W3或W4。
我还认为我可以用:
pd.Series.add(df.groupby("W1")["WP"].sum(), df.groupby("W2")["WP"].sum(), etc., fill_value=0)
但是,如果我放置三个以上的 groupby,就会出现错误。
我怎样才能实现我想做的事情?
您可以使用 melt
来展平数据框并计算每个玩家的分数。
df1 = df.melt(['WP', 'LP'], var_name='W/L', value_name='Player').dropna()
df1['Points'] = np.where(df1['W/L'].str[0] == 'W', df1['WP'], df1['LP'])
out = df1.groupby('Player', as_index=False)['Points'].sum() \
.sort_values('Points', ascending=False, ignore_index=True)
输出
Player | Points |
---|---|
Max | 14 |
Paddy | 6 |
Johann | 4 |
Vain | 4 |
Jonas | 3 |
Marvin | 1 |
Matthi | -1 |
Johannes | -2 |
Nille | -3 |
Markus | -9 |
Timi | -17 |
检查 df1
以查看中间数据帧。
IIUC,melt
重塑,根据列名计算点(如果以 W
开头),以及 grouby
+sum
:
import numpy as np
(df
.melt(id_vars=['WP','LP'], value_name='name')
.assign(points=lambda d: np.where(d['variable'].str.startswith('W'), d['WP'], d['LP']))
.groupby('name')['points'].sum()
)
输出:
name
Johann 4.0
Johannes -2.0
Jonas 3.0
Markus -9.0
Marvin 1.0
Matthi -1.0
Max 14.0
Nille -3.0
Paddy 6.0
Timi -17.0
Vain 4.0
Name: points, dtype: float64