大CSV文件处理技巧

在数据分析领域,处理大型CSV文件是一项常见任务。本文将探讨几种不同的方法来高效处理这些文件,包括使用PythonPandas库、Julia语言以及云计算服务GCP Big Query。

数据加载

Python中,最常用的加载CSV文件的方式是使用Pandas库中的DataFrame。以下是一个示例代码,展示了如何加载一个20GB大小的CSV文件,该操作耗时约4分24秒。

import pandas as pd testset = pd.read_csv(testset_file)

为了提高加载速度,可以采用32位数据类型。使用以下代码,加载相同20GB的CSV文件仅需2分26秒,速度提升了近2倍。

%%time thead = pd.read_csv(testset_file, nrows=5) # 仅读取几行以获取列标题 dtypes = dict(zip(thead.columns.values, ['int32', 'float32', 'int8', 'float32', 'float32', 'bool'])) # 根据数据页面指定的数据类型 del thead print('Datatype used for each column:n', json.dumps(dtypes)) testset = pd.read_csv(testset_file, dtype=dtypes) testset.info()

数据分析

数据分析可以通过DataFrame轻松完成。例如,以下代码展示了如何通过“passband”字段对数据进行分组并计算平均值,该操作耗时约1分29秒。

testset[["passband","flux"]].groupby(by=["passband"]).mean()

数据转换

在DataFrame中,可以使用transform函数对每行数据进行转换。例如,以下代码展示了如何通过乘以两个列“flux”和“flux_err”来计算新列“ff”。

%%time testset["ff"] = testset[["flux","flux_err"]].apply(lambda x: x[0]*x[1], axis=1)

然而,对于20GB大小的数据集,此操作无法完成,Jupyter笔记本内核会自重启。测试机器是iMac,仅配备了8GB内存,很可能是由于内存不足。

技巧2:使用NumPy数组

DataFrame.apply操作较慢,即使对于436MB的CSV文件,完成操作仍需1分6秒。为了加快速度,可以将DataFrame转换为NumPy数组,然后使用向量化函数或“map”函数进行转换。

f = lambda x,y: x*y vf = np.vectorize(f) %%time vf(testset["flux"].values,testset["flux_err"].values)

向量化函数耗时约2秒完成,而“Map”函数耗时约6秒完成。

技巧3:使用DataTable

除了PandasDataFrame,还有其他许多包可以加载和处理大量数据,其中之一就是“DataTable”,其速度比DataFrame快得多。DataTable的使用与DataFrame类似,但加载相同20GB的CSV文件仅需35秒。

import datatable as dt from datatable import (dt, f, by, ifelse, update, sort, count, min, max, mean, sum, rowsum) %%time dt_df = dt.fread(testset_file) %%time dt_df[:, mean(f.flux), by('passband')]

尽管上述分组聚合操作耗时约1分23秒,与DataFrame的性能相似。

除了Python,Julia是另一个在数据科学领域崛起的编程语言。Julia是一种高性能语言。以下是加载相同CSV文件、执行相同分组聚合和转换函数的代码。

using DataFrames using CSV @time df = DataFrame(CSV.File(file; types=Dict(:object_id => Int32, :mjd => Float32, :passband => Int8,:flux => Float32, :flux_err => Float32, :detected => Bool))) @time df_mean = combine(groupby(df,:passband),:flux => mean => :mean) @time transform!(df, [:flux,:flux_err] => ByRow(*) => :Err)

结果显示:读取CSV文件耗时5分钟,分组聚合耗时27秒,转换耗时12秒。尽管加载CSV文件的时间与Python相似,但聚合和转换非常快。最重要的是,与Python相比,Julia的内存占用要小得多。

gsutil -o "GSUtil:max_upload_compression_buffer_size=8G" -m cp -J test_set.csv gs://<bucket-name> SELECT passband,avg(flux) FROM `iwasnothing-self-learning.myloadtest.df` group by passband; SELECT object_id, flux*flux_err as ff FROM `iwasnothing-self-learning.myloadtest.df` ;
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485