我有一个包含一些调查结果的DataFrame;每列是对问题的回答。但是,对于允许从复选框中获得多个(< 10)答案的问题,该列已将这些答案与“响应1已检查|响应4已检查|响应6已检查...”进行连接,因此我无法只是根据预定义的顺序拆分列,因为它没有说明什么时候没有检查。
ID NormalResponse MultipleCheckboxResponse
1 Answer3 Response 3
2 Answer1 Response 1| Response 7
3 Answer2 Response 2| Response 4| Response 7
4 Answer2 Response 2 | Response 3
如何将这些原因拆分为新列,最好只使用布尔标记或单元格中的1/0来确定它是否已标记。
我想看看
ID NormalResponse Response1 Response2 Response3 Response4...
1 Answer3 0 0 1 0
2 Answer1 1 0 0 0
3 Answer2 0 1 0 1
4 Answer2 0 1 1 0
答案 0 :(得分:3)
您可以在执行一些字符串操作后使用get_dummies
删除垂直条|
周围的空格:
>>> resp = df.MultipleCheckboxResponse.str.replace("[\s]*\|[\s]*", "|")
>>> dummies = resp.str.get_dummies(sep="|")
>>> df.iloc[:,:2].join(dummies)
ID NormalResponse Response 1 Response 2 Response 3 Response 4 Response 7
0 1 Answer3 0 0 1 0 0
1 2 Answer1 1 0 0 0 1
2 3 Answer2 0 1 0 1 1
3 4 Answer2 0 1 1 0 0
请注意,这只会为实际看到的响应生成列。如果您想要response6
列,即使没有人报告过响应6,那么您需要自己添加循环。
答案 1 :(得分:2)
假设你有一个像这样的数据框
df
# ID NormalResponse MultipleCheckboxResponse
#0 1 Answer3 Response3
#1 2 Answer1 Response1|Response7
#2 3 Answer2 Response2|Response4|Response7
#3 4 Answer2 Response2|Response3
您可以执行以下操作
responses = df.MultipleCheckboxResponse.unique() # find unique responses in each column
u_response = set( [ x for sublist in responses for x in sublist.split('|') ] ) # find total unique responses in dataframe (maps the 2d list responses to a 1d list)
#{'Response1', 'Response2', 'Response3', 'Response4', 'Response7'}
(注意,set函数仅返回唯一值)。此时,您可以迭代唯一的响应。对于每个响应变量,您应该
MultiCheckboxResponse
列中,请检查每一行。如果是,请将行val设置为1。循环应该是这样的。
for col in u_response:
df[col] = 0 # initialize the col
df.loc[df.MultipleCheckboxResponse.str.contains(col), col] = 1 # adjust as necessary
df
# ID NormalResponse MultipleCheckboxResponse Response7 Response4 \
#0 1 Answer3 Response3 0 0
#1 2 Answer1 Response1|Response7 1 0
#2 3 Answer2 Response2|Response4|Response7 1 1
#3 4 Answer2 Response2|Response3 0 0
# Response2 Response3 Response1
#0 0 1 0
#1 0 0 1
#2 1 0 0
#3 1 1 0
有关处理文本数据的更多建议,请参阅here。
您似乎有无关的空格,因此您可能希望将u_response
代码行更改为
u_response = set( [ x.strip() for sublist in responses for x in sublist.split('|') ]
我们添加了strip
方法。这样您的列标题就没有空格。
答案 2 :(得分:0)
更新:上面至少有一个答案比我的好得多。不要浪费你的时间。
Pandas Series模块具有字符串操作功能,可以在这里派上用场。让我们先尝试一下:
from pandas import Series
response_series = df['MultipleCheckboxResponse']
split_responses = response_series.str.split('|')
这将拆分连锁的回复。返回的系列中的每个元素都是一个包含该行中每个响应的列表。从这里我们可以遍历系列的长度,以及系列中每个列表的长度,将每个单独的响应放在原始数据帧的新列中。
for i in range(0, len(split_responses)):
for j in range(0, len(split_responses.iloc[i]+1):
df[j+4][i] = split_responses.iloc[i][j]