如何高效拆分列表数据按规则填充到pandas DataFrame
商品列表转DataFrame的高效实现方案
你原来的写法存在两个明显问题:一是逐行创建DataFrame再调用append拼接的效率极低,数据量稍大时性能会非常差,且append方法在新版pandas中已经被弃用;二是硬编码不同长度下的字段索引,不仅代码冗余,后续如果原始字符串中间新增其他字段(比如划线价、会员标)很容易取错值,另外你原代码里无折扣商品的unit字段取了split后的第3位(索引2),实际那个位置是商品价格,属于索引写错的bug。
这类电商爬取的竖线分隔字符串,首尾的固定字段位置是稳定的:第1位永远是商品名,最后1位永远是无效的「Add to cart」按钮文本,倒数第2位是单位价格,倒数第3位是商品当前售价,中间夹的可变长度字段里只有带%的内容是折扣信息,完全不需要写分支判断拆分长度。
实现代码
import pandas as pd # 原始商品列表 raw_list = [ "Onion per Pack|500 g|Rp18,100|Rp3,700 / 100 g|Add to cart", "Shallot per Pack|250 g|-|49%|Rp22,300|Rp11,300|Rp4,600 / 100 g|Add to cart", "Spring Onion per Pack|250 g|Rp7,000|Rp2,800 / 100 g|Add to cart", "Green Beans per Pack|250 g|Rp5,900|Rp2,400 / 100 g|Add to cart", ] # 一次性完成所有字符串拆分 split_result = [s.split("|") for s in raw_list] # 按规则提取字段直接生成DataFrame df = pd.DataFrame({ "name": [item[0] for item in split_result], "unit": [item[1] for item in split_result], "discount": [next((seg for seg in item if seg.endswith("%")), "") for item in split_result], "price": [item[-3] for item in split_result], "unit price": [item[-2] for item in split_result] })
方案优势
- 性能更高:用列表推导式一次性生成所有列的数据,没有逐行拼接DataFrame的冗余操作,万级数据量下处理速度比原循环写法快两个数量级
- 鲁棒性更强:不依赖拆分后的总长度判断字段位置,哪怕后续原始字符串中间新增营销标签、划线价等可变字段,只要首尾固定字段的相对位置不变,代码不需要修改;折扣通过内容特征(带%符号)匹配,不会因为中间字段增减取错值
- 代码更简洁:去掉了重复的
split调用和分支判断,逻辑清晰易维护
如果后续需要做价格计算,可以追加几行代码做类型清洗:
# 折扣转0-1的浮点数 df["discount"] = df["discount"].str.rstrip("%").astype("float") / 100 # 价格转整数(去掉Rp和千分位逗号) df["price"] = df["price"].str.strip("Rp").str.replace(",", "").astype("int") df["unit price"] = df["unit price"].str.extract(r"Rp([\d,]+)").squeeze().str.replace(",", "").astype("int")
内容的提问来源于stack exchange,提问作者Hal
相关产品推荐
相关产品推荐

