如何在Python中提取pandas列中重复结构子串并规整数据
问题描述
我有一份格式特殊的调查问卷答案数据表,保存为CSV文件。将其导入为pandas DataFrame后,不同section对应不同列,每列包含多个part,格式示例为「part 1: A; part 2: B; ...」。示例代码如下:
from io import StringIO import pandas as pd INDATA = StringIO('''Response 1,Response 2 part 1: A; part 2: B; part 3: A; part 4: B; part 5: B,part 1: A; part 2: B; part 3: B; part 4: A ''') df = pd.read_csv(INDATA, sep=',')
希望将数据整理为以下两种格式之一:
- 每个part的结果作为单独列,示例如下:
| R1 | R2 | R3 | ... | R9 | | –- | –- | –- | –-- | –- | | A | B | A | ... | A |
- 将每列的所有part结果整理为列表,示例如下:
| Response1 | Response2 | | [A, B, A, B, B] | [A, B, B, A] |
请问使用re模块实现是否可行?有没有更优的解决方案?
解决方案
关于re模块的可行性
使用re模块完全可行,能通过正则匹配每个part后的答案内容。不过pandas内置的字符串处理API已经足够简洁高效,无需额外写复杂的原生re逻辑;当然如果涉及更特殊的匹配规则,re依然是可靠选项。
格式1:每个part单独列为新列
利用str.extractall提取所有part答案,再重排为宽表:
import pandas as pd from io import StringIO INDATA = StringIO('''Response 1,Response 2 part 1: A; part 2: B; part 3: A; part 4: B; part 5: B,part 1: A; part 2: B; part 3: B; part 4: A ''') df = pd.read_csv(INDATA, sep=',') # 匹配part后答案的正则 pattern = r'part \d+: (\w+)' # 对每列提取所有答案,展开后转置调整结构 result = df.apply(lambda col: col.str.extractall(pattern)[0].reset_index(drop=True)).T # 重命名列为R1、R2... result.columns = [f'R{i+1}' for i in range(result.shape[1])] print(result)
输出会将所有part的答案按顺序拆分为独立列,完全符合需求。
格式2:将每列的part结果整理为列表
用str.findall直接提取所有答案并转为列表:
import pandas as pd from io import StringIO INDATA = StringIO('''Response 1,Response 2 part 1: A; part 2: B; part 3: A; part 4: B; part 5: B,part 1: A; part 2: B; part 3: B; part 4: A ''') df = pd.read_csv(INDATA, sep=',') pattern = r'part \d+: (\w+)' result = df.apply(lambda col: col.str.findall(pattern)) # 可选:去掉列表外层的单引号,让格式更贴近示例 result = result.applymap(lambda x: str(x).replace("'", "")) print(result)
处理后每列的值会变成包含所有part答案的列表,和示例格式一致。
更优方案说明
上述方法本质上用到了正则,但通过pandas的str.extractall和str.findall封装了re的底层逻辑,代码更简洁且贴合pandas的数据流处理习惯,比直接用re模块手动循环处理效率更高,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者striatum
相关产品推荐
相关产品推荐

