jpp*_*jpp 12 python csv performance dataframe pandas
我有一个笨拙的CSV文件,它有多个分隔符:非数字部分的分隔符是','
数字部分';'
.我想尽可能高效地构建数字部分之外的数据框.
我做了5次尝试:其中,使用正则表达式,使用,使用的converters
参数.它们比读取整个CSV文件慢2倍,没有转换.这对我的用例来说太慢了.pd.read_csv
engine='python'
str.replace
我知道这种比较不像是喜欢,但它确实表明整体不良的性能不是由I/O驱动的.有没有更有效的方法将数据读入数字Pandas数据帧?还是等效的NumPy数组?
以下字符串可用于基准测试目的.
# Python 3.7.0, Pandas 0.23.4
from io import StringIO
import pandas as pd
import csv
# strings in first 3 columns are of arbitrary length
x = '''ABCD,EFGH,IJKL,34.23;562.45;213.5432
MNOP,QRST,UVWX,56.23;63.45;625.234
'''*10**6
def csv_reader_1(x):
df = pd.read_csv(x, usecols=[3], header=None, delimiter=',',
converters={3: lambda x: x.split(';')})
return df.join(pd.DataFrame(df.pop(3).values.tolist(), dtype=float))
def csv_reader_2(x):
df = pd.read_csv(x, header=None, delimiter=';',
converters={0: lambda x: x.rsplit(',')[-1]}, dtype=float)
return df.astype(float)
def csv_reader_3(x):
return pd.read_csv(x, usecols=[3, 4, 5], header=None, sep=',|;', engine='python')
def csv_reader_4(x):
with x as fin:
reader = csv.reader(fin, delimiter=',')
L = [i[-1].split(';') for i in reader]
return pd.DataFrame(L, dtype=float)
def csv_reader_5(x):
with x as fin:
return pd.read_csv(StringIO(fin.getvalue().replace(';',',')),
sep=',', header=None, usecols=[3, 4, 5])
Run Code Online (Sandbox Code Playgroud)
检查:
res1 = csv_reader_1(StringIO(x))
res2 = csv_reader_2(StringIO(x))
res3 = csv_reader_3(StringIO(x))
res4 = csv_reader_4(StringIO(x))
res5 = csv_reader_5(StringIO(x))
print(res1.head(3))
# 0 1 2
# 0 34.23 562.45 213.5432
# 1 56.23 63.45 625.2340
# 2 34.23 562.45 213.5432
assert all(np.array_equal(res1.values, i.values) for i in (res2, res3, res4, res5))
Run Code Online (Sandbox Code Playgroud)
基准测试结果:
%timeit csv_reader_1(StringIO(x)) # 5.31 s per loop
%timeit csv_reader_2(StringIO(x)) # 6.69 s per loop
%timeit csv_reader_3(StringIO(x)) # 18.6 s per loop
%timeit csv_reader_4(StringIO(x)) # 5.68 s per loop
%timeit csv_reader_5(StringIO(x)) # 7.01 s per loop
%timeit pd.read_csv(StringIO(x)) # 1.65 s per loop
Run Code Online (Sandbox Code Playgroud)
我愿意使用命令行工具作为最后的手段.在这种程度上,我已经包含了这样一个答案.我希望有一个纯Python或Pandas解决方案,效率相当.
到目前为止,最有效的解决方案,我发现是使用专门的命令行工具,以取代";"
与","
和然后读入大熊猫.Pandas或纯Python解决方案在效率方面并不接近.
从本质上讲,使用CPython或用C/C++编写的工具可能会胜过Python级别的操作.
例如,使用查找和替换文本:
import os
os.chdir(r'C:\temp') # change directory location
os.system('fart.exe -c file.csv ";" ","') # run FART with character to replace
df = pd.read_csv('file.csv', usecols=[3, 4, 5], header=None) # read file into Pandas
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
839 次 |
最近记录: |