我有一个数据框
import pandas as pd
df=pd.DataFrame({'Players': [ 'Sam', 'Greg', 'Steve', 'Sam',
'Greg', 'Steve', 'Greg', 'Steve', 'Greg', 'Steve'],
'Wins': [10,5,5,20,30,20,6,9,3,10],
'Losses': [5,5,5,2,3,2,16,20,3,12],
'Type': ['A','B','B','B','A','B','B','A','A','B'],
})
如果我想总结一下,我可以手动制作另一个数据帧:
p=df.groupby('Players')
summary = pd.DataFrame({'Total Games': p.Players.count(),
'Average Wins':p.Wins.mean(),
'Greatest Wins':p.Wins.max(),
'Unique games':p.Type.nunique()})
让我们说如果列X存在,我想自动化这个汇总过程来创建数据帧执行汇总Y这样做的最佳方法是什么?我试过使用字典,但我认为我做错了
p=df.groupby('Players')
sumdict = {'Total Games': ['Players', p.Players.count()],
'Average Wins':['Wins', p.Wins.mean()],
'Greatest Wins':['Wins', p.Wins.max()],
'Unique games':['Type', p.Type.nunique()],
'Max Score':['Score', p.Score.max()]}
summary=pd.DataFrame()
for key, value in sumdict.items():
if value[0] in df.columns:
data = pd.DataFrame({key: value[1],})
summary=summary.append(data)
else:
continue
答案 0 :(得分:1)
Pandas DataFrame
支持大多数dict
方法,包括get
(允许您将值替换为空键)。因此,您可以在所有列上执行所需的统计信息,然后获取所需列的值,将空Series
替换为缺少的列,然后删除NaN
列(我使用Bad Value
证明丢失的列会发生什么):
eser = pd.Series()
count = p.count().max(axis=1)
all_max = p.max()
score_max = all_max.get('Score', eser)
wins_max = all_max.get('Wins', eser)
wins_mean = p.mean().get('Wins', eser)
type_nunique = p.agg(lambda x: x.nunique()).get('Type', eser)
summary = pd.DataFrame({'Total Games': count,
'Average Wins': wins_mean,
'Greatest Wins': wins_max,
'Unique games': type_nunique,
'Max Score': score_max})
summary.dropna(axis=1, how='all', inplace=True)
或单行(包括两次计算所有列的max
,这对于少量值应该不是问题):
summary = pd.DataFrame({'Total Games': p.count().max(axis=1),
'Average Wins': p.mean().get('Wins', pd.Series()),
'Greatest Wins': p.max().get('Wins', pd.Series()),
'Unique games': p.agg(lambda x: x.nunique()).get('Type', pd.Series()),
'Max Score': p.max().get('Score', pd.Series())}).dropna(axis=1, how='all')
两种方法的结果:
Average Wins Greatest Wins Total Games Unique games
Greg 11 30 4 2
Sam 15 20 2 2
Steve 11 20 4 2
没有dropna
:
Average Wins Greatest Wins Max Score Total Games Unique games
Greg 11 30 NaN 4 2
Sam 15 20 NaN 2 2
Steve 11 20 NaN 4 2
如果性能是一个问题,上面的内容会很慢,因为它们需要在所有列上计算多个统计信息,这意味着统计信息正在被计算然后被丢弃。更快但更丑陋的方法类似于在dict
上使用循环的方法。
您的实施问题是dict
项目不懒惰评估,在创建dict
时评估它们,这意味着它仍然尝试访问不存在的列。
下面的方法同时获取项目并仅在找到列时应用函数(对count
情况进行特殊处理,因为任何现有列都可以工作):
sumdict = {'Total Games': (None, 'count'),
'Average Wins': ('Wins', 'mean'),
'Greatest Wins': ('Wins', 'max'),
'Unique games': ('Type', 'nunique'),
'Max Score': ('Score', 'max')}
summary = []
for key, (column, op) in sumdict.items():
if column is None:
res = p.agg(op).max(axis=1)
elif column not in df:
continue
else:
res = p[column].agg(lambda x: getattr(x, op)())
summary.append(pd.DataFrame({key: res}))
summary = pd.concat(summary, axis=1)
它提供与上述方法相同的结果,尽管列顺序不同。