这是数据框“df”中的数据:
Document Name Time
SPS2315511 A 1 HOUR
SPS2315512 B 1 - 2 HOUR
SPS2315513 C 2 - 3 HOUR
SPS2315514 C 1 HOUR
SPS2315515 B 1 HOUR
SPS2315516 A 2 - 3 HOUR
SPS2315517 A 1 - 2 HOUR
我使用下面的代码,它给出了数据透视表中的计数摘要,
table = pivot_table(df, values=["Document"],
index=["Name"], columns=["Time"],
aggfunc=lambda x: len(x),
margins=True, dropna=True)
但我想要的是在右键单击数据透视表并选择“显示值为 - >行总计百分比”时的行计算百分比。由于我的文档是非数字值,我无法得到它。
Count of Document Column Labels
Name 1 HOUR 1 - 2 HOUR 2 - 3 HOUR Grand Total
A 33.33% 33.33% 33.33% 100.00%
B 50.00% 50.00% 0.00% 100.00%
C 50.00% 0.00% 50.00% 100.00%
Grand Total 42.86% 28.57% 28.57% 100.00%
任何人都可以帮我找出一种方法来获得这个结果吗?
我正在尝试操纵枢轴数据,这将给出行总数,而不是数据框中的数据,我想要的是“行总数的百分比”。最重要的是,我的所有数据都是非数字值......
答案 0 :(得分:7)
@maxymoo注意到的可能副本与解决方案非常接近,但我会继续将其作为答案进行编写,因为有一些差异并非完全直截了当。
table = pd.pivot_table(df, values=["Document"],
index=["Name"], columns=["Time"],
aggfunc=len, margins=True,
dropna=True, fill_value=0)
Document
Time 1 - 2 HOUR 1 HOUR 2 - 3 HOUR All
Name
A 1 1 1 3
B 1 1 0 2
C 0 1 1 2
All 2 3 2 7
主要的调整是添加fill_value=0
,因为你真正想要的是一个计数值为零,而不是NaN。
然后你基本上可以使用@maxymoo链接的解决方案,但你需要使用iloc
或类似的b / c表格列现在有点复杂(作为数据透视表的多索引结果)
table2 = table.div( table.iloc[:,-1], axis=0 )
Document
Time 1 - 2 HOUR 1 HOUR 2 - 3 HOUR All
Name
A 0.333333 0.333333 0.333333 1
B 0.500000 0.500000 0.000000 1
C 0.000000 0.500000 0.500000 1
All 0.285714 0.428571 0.285714 1
你还有一些小的格式化工作要做(翻转第一列和第二列并转换为%),但这些是你正在寻找的数字。
顺便说一下,这里没有必要,但你可能想考虑将'Time'转换为有序的分类变量,这是解决列排序问题的一种方法(我认为),但可能值得也可能不值得这取决于你对数据做了什么。
答案 1 :(得分:0)
您可以使用类似的东西
df = pd.DataFrame({'Document':['SPS2315511','SPS2315512','SPS2315513','SPS2315514','SPS2315515','SPS2315516','SPS2315517'],
'Name':['A','B','C','C','B','A','A'],
'Time': ['1 HOUR','1 - 2 HOUR','2 - 3 HOUR','1 HOUR','1 HOUR','2 - 3 HOUR','1 - 2 HOUR']})
pd.crosstab(index= df.Name, columns= df.Time, values= df.Document, aggfunc = np.count_nonzero
,margins=True,margins_name='Total',normalize= 'index')