如何用Python快速读取含数组列的CSV为Pandas DataFrame?
问题描述
我有一些包含数组列的CSV文件,示例如下:
a,b,c 1,1|2|3,4.5|5.5|6.5 2,7|8|9,10.5|11.5|12.5
其中字段分隔符为,,数组元素的分隔符为|(可按需更改)。我想直接用Python将其读取为Pandas DataFrame,且字段b、c保持数组/Series类型。
当前我采用的方法是先以字符串格式读取CSV:
df = pd.read_csv('data.csv', dtype='str')
再使用np.fromstring将字符串转换为numpy数组:
import numpy as np import pandas as pd type_dict = { "a": "int", "b": "int", "c": "float" } def make_split(text, dt): return np.fromstring(text, sep="|", dtype=dt) df = df.apply(lambda x: x.apply(make_split, dt=type_dict[x.name]))
但该方法处理我的文件需要数分钟,请问是否有更快的方案?
优化方案
方案1:用str.split结合向量化操作替代逐元素处理
避免嵌套apply的逐行处理,改用Pandas原生优化的字符串方法完成转换,效率提升明显:
import pandas as pd import numpy as np # 读取时直接指定a列类型,b、c保留字符串 df = pd.read_csv('data.csv', dtype={'a': int, 'b': str, 'c': str}) # 批量转换数组列 df['b'] = df['b'].str.split('|').apply(lambda x: np.array(x, dtype=int)) df['c'] = df['c'].str.split('|').apply(lambda x: np.array(x, dtype=float))
方案2:读取阶段用converters参数直接转换
在pd.read_csv读取时就指定转换器,省去后续的全表处理步骤:
import pandas as pd import numpy as np def convert_b(s): return np.array(s.split('|'), dtype=int) def convert_c(s): return np.array(s.split('|'), dtype=float) df = pd.read_csv('data.csv', dtype={'a': int}, converters={'b': convert_b, 'c': convert_c})
方案3:用标准库csv批量读取构造DataFrame
针对超大型文件,直接用Python标准库csv读取后批量构造数据,减少Pandas内部的额外开销:
import csv import pandas as pd import numpy as np data = {'a': [], 'b': [], 'c': []} with open('data.csv', 'r') as f: reader = csv.DictReader(f) for row in reader: data['a'].append(int(row['a'])) data['b'].append(np.array(row['b'].split('|'), dtype=int)) data['c'].append(np.array(row['c'].split('|'), dtype=float)) df = pd.DataFrame(data)
方案4:更换数组存储格式为JSON(推荐)
如果可以修改CSV生成规则,将数组列存储为JSON格式,读取时用json.loads解析,效率和规范性都更优:
示例CSV(数组存为JSON):
a,b,c 1,"[1,2,3]","[4.5,5.5,6.5]" 2,"[7,8,9]","[10.5,11.5,12.5]"
读取代码:
import pandas as pd import json df = pd.read_csv('data.csv', converters={'b': json.loads, 'c': json.loads}, dtype={'a': int}) # 可选:转成numpy数组 df['b'] = df['b'].apply(np.array) df['c'] = df['c'].apply(np.array)
内容的提问来源于stack exchange,提问作者c111
相关产品推荐
相关产品推荐

