我有一些来自 Google Sheets 的数据,其中有一个多答案问题,如下所示:
Q1 Q2 ... Multi-Response
0 ... ... ... "A; B"
1 ... ... ... "B; C"
2 ... ... ... "D; F"
3 ... ... ... "A; B; F"
(请注意空格,分隔符是
'; '
,这是出于奇怪的解决方法原因,调查作者编写问题的方式以及 Google 表格选择输出响应表的方式)
我正在尝试扩展它,这样我就可以对其进行一些 k 模式聚类:
Q1 Q2 ... A B C D F
0 ... ... ... 1 1 0 0 0
1 ... ... ... 0 1 1 0 0
2 ... ... ... 0 0 0 1 1
3 ... ... ... 1 1 0 0 1
这个想法或多或少地将每个响应列表映射到一系列“你同意吗?是/否”问题。
但我不太清楚如何将数据帧转换为该格式。我尝试使用
pivot_table
和 get_dummies
,但如果它可以做到这一点,我不清楚它到底是如何工作的。
我可以通过
获取回复表multi_selection_question = data.keys()[-1]
expanded = data[multi_selection_question].str.split('; ', expand=True)
产生类似的东西
0 1 2
0 A B None
1 B C None
2 D F None
3 A B F
以及一个问题列表,这些问题将是正确的列名称:
questions = pandas.Series(expanded.values.flatten()).unique()
但是我看到的
pivot_table
或 get_dummies
的示例似乎需要不同格式的数据,并且列结构比输出的更一致。例如,使用 get_dummies
为每个 (column,question)
对创建一个单独的类别,因此对于上面的示例表 - 2_F
、3_F
、1_B
、2_B
等
当然,我可以求助于几个循环并逐行构建一个新的数据框并
concat
它,但是通常pandas中有更好的方法。
您可以尝试以下方法:
import pandas as pd
# sample data
data = pd.DataFrame({'Question': ["A; B", "B; C", "A; D", "A; C", "B; D"]})
print(data)
它给出:
Question
0 A; B
1 B; C
2 A; D
3 A; C
4 B; D
然后:
df1 = (data["Question"]
.str.split('; ', expand=True)
.stack()
.droplevel(1)
)
df2 = pd.crosstab(index=df1.index, columns=df1)
df2.index.name = None
df2.columns.name = None
print(df2)
结果:
A B C D
0 1 1 0 0
1 0 1 1 0
2 1 0 0 1
3 1 0 1 0
4 0 1 0 1