这是我的数据:
{'SystemID': {0: '95EE8B57',
1: '5F891F03',
2: '5F891F03',
3: '5F891F03',
4: '95EE8B57'},
'Activity': {0: '2', 1: '4', 2: '6', 3: '8', 4: '1'}}
我需要总结一下“活动”的数据集。对于每个“SystemID”,我需要计算4个类别中的每一个的百分比:小于2,2或更大但小于4,4或更大但小于6,6或更大。
以上代码段的结果将是:
{'SystemID': {0: '95EE8B57',
1: '5F891F03'},
'Activity-perc-less2': {0: '50', 1: '0'},
'Activity-perc-less4': {0: '50', 1: '0'},
'Activity-perc-less6': {0: '0', 1: '33.3'},
'Activity-perc-6-and-above': {0: '0', '66.7'}}
这该怎么做?
我不确定这是否是最优雅的方式,但以下似乎产生了我想要的东西:
dict2 = {'SystemID': {0: '95EE8B57',
1: '5F891F03',
2: '5F891F03',
3: '5F891F03',
4: '95EE8B57'},
'Activity': {0: '2', 1: '4', 2: '6', 3: '8', 4: '1'}}
df2 = pd.DataFrame.from_dict(dict2)
bins = np.array([2, 4, 6])
df2.Activity = df2.Activity.astype(int)
#Solution:
df2['ActBins'] = np.digitize(df2.Activity, bins)
table = pd.pivot_table(df2, index=["SystemID"],columns=["ActBins"],
aggfunc=len, margins=True, dropna=True,fill_value=0)
table2 = 100*table.div( table.iloc[:,-1], axis=0 )
table3 = table2.iloc[[0,1],[0,1,2,3]]
table3.columns = ['Activity-perc-less2', 'Activity-perc-less4',
'Activity-perc-less6', 'Activity-perc-6-and-above']
print(table3)
如果有人找到更优雅的解决方案,请发布。
编辑:
刚刚将上述解决方案抽象为一个函数:
def perc_pivot (df, ind, col, bin):
df[col+'Bins'] = np.digitize(df[col], bins)
table = pd.pivot_table(df, index=[ind],columns=[col+'Bins'],
aggfunc=len, margins=True, dropna=True,fill_value=0)
table = 100*table.div( table.iloc[:,-1], axis=0 )
table.drop(table.tail(1).index,inplace=True)
return table.drop(table.columns[len(table.columns)-1], axis=1)
一个简单的电话
df3 = perc_pivot(df2, 'SystemID', 'Activity', bins)
产生所需的输出(除了列名)。可以在之后手动完成列的重命名。
函数中的代码看起来仍然有点笨拙,所以我欢迎可能使它更优雅的建议。