多轮s.str.split调用性能优化及Dict化向量式实现问询
问题描述
现有一个包含Interventions列的DataFrame,该列部分条目以|分隔多个干预项,需完成以下处理:
- 按
|拆分但不扩展为多列; - 拆分为新行;
- 按首个
:拆分; - 扩展为两列。
当前实现代码为:
interventions.str.split('|',expand=False).explode().str.split(': ', expand=True, n=1)
经cProfile分析耗时9.940秒,存在大量函数调用,现需解决:
- 是否有更高效的实现方式?
- 能否将每个干预项转为dict并以向量式方式展开为两列?
高效实现方案
一、优化字符串拆分与展开流程
Pandas的str方法虽便捷,但底层函数调用开销较高。以下两种方案可大幅减少调用次数、提升速度:
方法1:用str.partition替代str.split(n=1)
str.partition在处理固定分隔符且仅需拆分前两部分时,底层开销远低于str.split(n=1),结合explode的完整实现:
# 拆分|并展开为行 split_exploded = df['Interventions'].str.split('|').explode() # 按首个: 拆分,直接得到三列(分隔符列可丢弃) result = split_exploded.str.partition(': ') # 整理列名并丢弃无用列 result = result.drop(columns=[1]).rename(columns={0: '干预类型', 2: '干预详情'})
方法2:Numpy向量化处理(超大数据集首选)
绕开Pandas的str方法调度开销,直接用Numpy字符串操作实现:
import numpy as np # 将列转为numpy数组,拆分|并拼接为一维数组 interv_array = df['Interventions'].dropna().to_numpy() split_array = np.concatenate([np.char.split(x, '|') for x in interv_array]) # 按首个: 拆分,得到结构化数组 split_col = np.char.partition(split_array, ': ') # 转为DataFrame result = pd.DataFrame({ '干预类型': split_col[:, 0], '干预详情': split_col[:, 2] })
二、转为Dict并向量式展开
若干预项为键: 值的统一结构,可转为单键字典后用pd.json_normalize向量式展开,适合键不固定的场景:
# 拆分|并展开为行,过滤空值 split_exploded = df['Interventions'].str.split('|').explode().dropna() # 用列表推导式批量转为单键字典(比apply高效) dict_list = [ {k.strip(): v.strip()} for item in split_exploded for k, v in [item.split(': ', maxsplit=1)] if ': ' in item ] # 向量式展开为列 result = pd.json_normalize(dict_list)
如果需要统一列名(比如所有可能的键都固定),可先提取所有键再补全缺失值:
all_keys = list({k for d in dict_list for k in d.keys()}) result = pd.json_normalize(dict_list).reindex(columns=all_keys)
性能选择建议
- 小数据集:优先用
str.partition方案,代码简洁且速度提升明显; - 大数据集:选Numpy向量化方案,或dict+
json_normalize方案(键不固定时); - 核心原则:避免多次嵌套
str方法调用,尽量合并为批量操作。
内容的提问来源于stack exchange,提问作者Vijay Tripathi
相关产品推荐
相关产品推荐

