我有一个数据框
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
最佳答案
熊猫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)
尽管列顺序不同,但结果与上述方法相同。
关于python - Pandas 根据存在的列生成数据框,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29964552/