我有一个像这样的扁平DataFrame:
我想将其转换为这样的DataFrame:
对于每个版本(Version)的每个测试(T),我想将在给定的李克特量表上映射的答案计数(为了演示目的,我将其缩减为3个条目)作为百分比。
T和版本的每种组合的李克特量表值的总和应总计为100%。
likert = {
'Agree': 1,
'Undecided': 2,
'Disagree': 3,
}
这怎么可能? 感谢您的帮助!
答案 0 :(得分:2)
可能不是最优雅的解决方案,但我认为这可以实现您的目标。假设您的数据框名为df
(我在各个刻度之间随机采样,因此我的df
并非您所描述的):
res = df.melt(id_vars=['T', 'Version'], value_vars=['Q1', 'Q2'], value_name='Scale')
这会将您的数据框转换为长格式:
# T Version variable Scale
# 0 1 A Q1 Undecided
# 1 1 A Q1 Disagree
# 2 1 A Q1 Undecided
# 3 1 A Q1 Agree
然后,您要计算变量的每个组合的大小,可以通过以下方式实现:
res = res.groupby(['T', 'Version', 'Scale', 'variable']).size()
哪种产量:
# T Version Scale variable
# 1 A Agree Q1 2
# Q2 1
# Disagree Q2 3
# Undecided Q1 2
# B Agree Q1 1
然后,将Q1
和Q2
移至各列,则按如下所示拆开最后一个索引级别:
res = res.unstack(level=-1).fillna(0)
# variable Q1 Q2
# T Version Scale
# 1 A Agree 2.0 1.0
# Disagree 0.0 3.0
# Undecided 2.0 0.0
最后,要计算前两个索引级别的每种组合的百分比:
res = res.groupby(level=[0, 1]).apply(lambda x: 100. * x / x.sum())
给出预期结果的
# variable Q1 Q2
# T Version Scale
# 1 A Agree 50.000000 25.000000
# Disagree 0.000000 75.000000
# Undecided 50.000000 0.000000
# B Agree 33.333333 0.000000
# Disagree 66.666667 66.666667