我在这里使用熊猫来分析大数据文件:http://www.nielda.co.uk/betfair/data/它们的大小约为100兆.
来自csv的每个负载需要几秒钟,然后有更多时间来转换日期.
我已经尝试加载文件,将日期从字符串转换为日期时间,然后将它们重新保存为pickle文件.但加载它们也需要几秒钟.
我可以使用哪些快速方法从磁盘加载/保存数据?
jor*_*ris 19
正如@chrisb所说,熊猫的read_csv
速度可能比csv.reader/numpy.genfromtxt/loadtxt
.我不认为你会找到更好的解析csv(作为一个注释,read_csv
不是'纯python'解决方案,因为CSV解析器是用C实现的).
但是,如果您必须经常加载/查询数据,解决方案是仅解析CSV一次,然后将其存储为另一种格式,例如HDF5.您可以使用pandas
(PyTables
在后台)有效地查询(docs).
请参阅此处,了解HDF5,csv和SQL与pandas的io性能:http://pandas.pydata.org/pandas-docs/stable/io.html#performance-considerations
还有一个可能相关的问题:"大数据"工作流程使用大熊猫
稍后发布此内容是为了回答一个类似的问题,该问题发现简单地使用开箱即用的 modin 是不够的。答案与 dask 类似 - 根据您的用例,组合使用以下所有策略以获得最佳结果。
关于缩放到大型数据集的pandas 文档有一些很棒的技巧,我将在这里总结:
usecols
使用或nrows
参数pd.read_csv
读入列或行的子集。例如,如果您的数据有很多列,但您只需要col1
和col2
列,请使用pd.read_csv(filepath, usecols=['col1', 'col2'])
。如果您要加载带有大量额外逗号的数据集(例如,行看起来像 ),这一点尤其重要。index,col1,col2,,,,,,,,,,,
在这种情况下,请使用nrows
仅读入数据的子集,以确保结果仅包含您需要的列。Series.astype
或 之pd.to_numeric
类的downcast
。chunksize
和iterator
参数来循环数据块并以较小的片段处理文件。有关更多详细信息,请参阅逐块迭代文件的文档或者,使用该low_memory
标志让 Pandas 在后端使用分块迭代器,但返回单个数据帧。此外,我认为您应该考虑一些特定于 csv 的事情:
dtypes
具有单一数据类型的参数来应用于所有列或列名的字典,数据类型对指示要读入的类型。或者,您可以提供converters
格式化日期、时间或其他数字数据(如果不在其中) pandas 识别的格式。engine='c'
来确保正在使用 C 引擎。如果您的文件无法被 C 引擎读取,我会尝试首先手动修复文件(例如,删除页脚或标准化分隔符),然后如果可能的话,使用 C 引擎进行解析。na_values
、keep_default_na
、date_parser
和 的converters
参数pd.read_csv
。目前,解释为 NaN 的默认值列表是['', '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN', '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A', 'NA', 'NULL', 'NaN', 'n/a', 'nan', 'null']
。例如,如果您的数字列具有编码为的非数字值,notANumber
那么这将被遗漏,并且会导致错误(如果您指定了 dtypes)或导致 pandas 重新启动。 -将整个列分类为对象列(对内存和速度来说超级不利!)。pd.read_csv
一遍又一遍地阅读文档。read_csv 的许多参数都有重要的性能考虑。pd.read_csv
经过优化以平滑可被视为 csv 的大量变化,并且更多的 magic pandas 必须准备好执行(确定类型、解释 nan、转换日期(可能)、跳过页眉/页脚、推断索引/列、处理坏行等)读取速度越慢。给它尽可能多的提示/约束,你可能会发现性能大幅提高!如果这还不够,其中许多调整也将适用于dask.dataframe API,因此这可以进一步很好地扩展。此外,如果可以选择,请将文件保存为稳定的二进制存储格式。Apache Parquet是一种很好的列式存储格式,支持 pandas,但还有许多其他格式(有关更多选项,请参阅Pandas IO 指南)。Pickles 跨 Pandas 版本可能有点脆弱(当然,任何二进制存储格式也一样,但这通常不太关心显式数据存储格式而不是 Pickles),并且 CSV 效率低下且未指定,因此需要类型转换和解释。
要检查的一件事是磁盘系统本身的实际性能。特别是如果您使用旋转磁盘(而不是 SSD),您的实际磁盘读取速度可能是性能的解释因素之一。因此,在进行太多优化之前,请检查将相同的数据读入内存(例如,mydata = open('myfile.txt').read()
)是否需要相同的时间。(只要确保你没有被磁盘缓存咬住;如果你加载相同的数据两次,第二次会快得多,因为数据已经在 RAM 缓存中了。)
在相信我在下面写的内容之前请参阅下面的更新
如果您的问题确实是解析文件,那么我不确定是否有任何纯 Python 解决方案可以帮助您。由于您知道文件的实际结构,因此不需要使用通用 CSV 解析器。
不过,可以尝试三件事:
csv
包和csv.reader
genfromtext
loadtxt
如果您可以将其与您的数据一起使用,那么第三个可能是最快的。同时它具有最有限的功能集。(这实际上可能会使其变得更快。)
crclayton
另外, 、 、BKay
、 、 等评论中给你的建议都EdChum
很好。
尝试不同的选择!如果它们不起作用,那么您将不得不用编译语言(编译的 Python 或 C)编写一些东西。
更新:我确实相信chrisb
下面所说的,即pandas
解析器很快。
那么使解析速度更快的唯一方法是用 C(或其他编译语言)编写特定于应用程序的解析器。CSV 文件的通用解析并不简单,但如果知道文件的确切结构,可能会有快捷方式。在任何情况下,解析文本文件都很慢,因此如果您可以将其转换为更容易接受的内容(HDF5、NumPy 数组),则加载将仅受 I/O 性能的限制。