几个月来,我在学习熊猫的过程中,一直在努力想出这个问题的答案。我在日常工作中使用SAS,它的核心支持很棒。然而,SAS作为一个软件是可怕的,还有许多其他原因。
有一天我希望用python和pandas取代我对SAS的使用,但我目前缺少一个用于大型数据集的非核心工作流。我说的不是需要分布式网络的“大数据”,而是大到内存放不下但小到硬盘驱动器放不下的文件。
我的第一个想法是使用hdfstore
在磁盘上保存大型数据集,并只将所需的部分放入数据流中进行分析。其他人提到MongoDB是一个更容易使用的替代方案。我的问题是:
完成以下工作的一些最佳实践工作流程是什么:
真实世界的例子将非常感谢,特别是从任何谁使用熊猫的“大数据”。
编辑--我希望它如何工作的示例:
我正试图找到一种执行这些步骤的最佳实践方法。阅读有关熊猫和pytables的链接时,添加一个新的专栏似乎是个问题。
编辑--专门回答Jeff的问题:
如果var1>2,则newvar='a';如果var2=4,则newvar='b'
。这些操作的结果是数据集中的每个记录都有一个新列。我很少会向数据集中添加行。我几乎总是在创建新的列(统计学/机器学习术语中的变量或特性)。
现在,在这个问题发生两年后,又出现了一只“出格”的熊猫:达斯克。太棒了!虽然它并不支持pandas的所有功能,但你可以在这方面做得很好。更新:在过去的两年中,它得到了持续的维护,并且有大量的用户社区在使用Dask。
现在,在这个问题四年后,又有一个高性能的“核心外”熊猫等价物在Vaex。它“使用内存映射、零内存复制策略和惰性计算以获得最佳性能(没有内存浪费)。”它可以处理数十亿行的数据集,并且不将其存储到内存中(使得甚至可以在次优硬件上进行分析)。
我认为上面的答案缺少了一个我发现非常有用的简单方法。
当我有一个文件太大而无法加载到内存中时,我会将该文件分解为多个较小的文件(按行或按列)
示例:如果30天的交易数据大小为30GB,我将其分解为每天1GB大小的文件。我随后分别处理每个文件,并在最后汇总结果
最大的优点之一是它允许并行处理文件(多线程或进程)
另一个优点是文件操作(如本例中的添加/删除日期)可以通过常规shell命令完成,这在更高级/复杂的文件格式中是不可能的
这种方法并不涵盖所有场景,但在许多场景中都非常有用
我经常以这种方式使用几十GB的数据,例如,我在磁盘上有通过查询读取的表,创建数据并追加回来。
有必要阅读本文后面的文档,了解如何存储数据的几个建议。
将影响数据存储方式的详细信息,例如:
尽可能提供详细信息;我可以帮你建立一个结构。
确保至少安装了pandas0.10.1
。
逐块读取迭代文件和多个表查询。
由于pytables被优化为按行操作(这就是您查询的内容),我们将为每组字段创建一个表。这样就很容易选择一小组字段(这将与一个大表一起工作,但这样做效率更高...我想我将来也许可以修复这个限制...这无论如何更直观):
(以下是伪代码。)
import numpy as np
import pandas as pd
# create a store
store = pd.HDFStore('mystore.h5')
# this is the key to your storage:
# this maps your fields to a specific group, and defines
# what you want to have as data_columns.
# you might want to create a nice class wrapping this
# (as you will want to have this map and its inversion)
group_map = dict(
A = dict(fields = ['field_1','field_2',.....], dc = ['field_1',....,'field_5']),
B = dict(fields = ['field_10',...... ], dc = ['field_10']),
.....
REPORTING_ONLY = dict(fields = ['field_1000','field_1001',...], dc = []),
)
group_map_inverted = dict()
for g, v in group_map.items():
group_map_inverted.update(dict([ (f,g) for f in v['fields'] ]))
读取文件并创建存储(本质上是执行append_to_multiple
执行的操作):
for f in files:
# read in the file, additional options may be necessary here
# the chunksize is not strictly necessary, you may be able to slurp each
# file into memory in which case just eliminate this part of the loop
# (you can also change chunksize if necessary)
for chunk in pd.read_table(f, chunksize=50000):
# we are going to append to each table by group
# we are not going to create indexes at this time
# but we *ARE* going to create (some) data_columns
# figure out the field groupings
for g, v in group_map.items():
# create the frame for this group
frame = chunk.reindex(columns = v['fields'], copy = False)
# append it
store.append(g, frame, index=False, data_columns = v['dc'])
现在文件中有了所有的表(实际上,如果您愿意,您可以将它们存储在单独的文件中,您可能不得不将文件名添加到group_map中,但这可能不是必需的)。
以下是获取列和创建新列的方式:
frame = store.select(group_that_I_want)
# you can optionally specify:
# columns = a list of the columns IN THAT GROUP (if you wanted to
# select only say 3 out of the 20 columns in this sub-table)
# and a where clause if you want a subset of the rows
# do calculations on this frame
new_frame = cool_function_on_frame(frame)
# to 'add columns', create a new group (you probably want to
# limit the columns in this new_group to be only NEW ones
# (e.g. so you don't overlap from the other tables)
# add this info to the group_map
store.append(new_group, new_frame.reindex(columns = new_columns_created, copy = False), data_columns = new_columns_created)
当您准备好进行POST_Processing时:
# This may be a bit tricky; and depends what you are actually doing.
# I may need to modify this function to be a bit more general:
report_data = store.select_as_multiple([groups_1,groups_2,.....], where =['field_1>0', 'field_1000=foo'], selector = group_1)
关于data_columns,实际上不需要定义任何data_columns;它们允许您根据列子选择行。例如。类似于:
store.select(group, where = ['field_1000=foo', 'field_1001>0'])
在最后的报表生成阶段,它们可能是您最感兴趣的(基本上,数据列与其他列是分离的,如果您定义了很多,这可能会影响效率)。
您还可能希望:
有问题的时候告诉我!
问题内容: 在学习pandas的过程中,我试图迷惑了这个问题很多月。我在日常工作中使用SAS,这非常有用,因为它提供了核心支持。但是,由于许多其他原因,SAS作为一个软件还是很糟糕的。 有一天,我希望用python和pandas取代我对SAS的使用,但是我目前缺少大型数据集的核心工作流程。我并不是说需要分布式网络的“大数据”,而是文件太大而无法容纳在内存中,但文件又足够小而无法容纳在硬盘上。 我的
在学习熊猫的过程中,我已经尝试了好几个月来找出这个问题的答案。我在日常工作中使用SAS,这是非常好的,因为它提供了非核心支持。然而,SAS作为一个软件是可怕的,原因还有很多。 有一天,我希望用python和pandas取代SAS的使用,但我目前缺乏大型数据集的核心外工作流。我说的不是需要分布式网络的“大数据”,而是文件太大而无法放入内存,但又太小而无法装入硬盘。 我的第一个想法是使用将大型数据集保
在学习熊猫的过程中,我已经尝试了好几个月来找出这个问题的答案。我在日常工作中使用SAS,这是非常好的,因为它提供了非核心支持。然而,SAS作为一个软件是可怕的,原因还有很多。 有一天,我希望用python和熊猫取代SAS,但我目前缺乏大型数据集的核心外工作流。我说的不是需要分布式网络的“大数据”,而是文件太大,无法放入内存,但又小到足以放入硬盘。 我的第一个想法是使用在磁盘上保存大型数据集,只将我
我正在使用谷歌工作表来保存共享项目的数据。我使用Google的Sheets API访问数据,用python处理数据,并尝试在function writer中使用batchUpdate更新Sheets文件。 如果我将此函数数据作为列表传递,它将按预期工作 GoogleapClient。错误。HttpError: 任何指点都将不胜感激。
问题内容: 我试图使用s或函数读取稍大的数据集,但我一直遇到s。数据框的最大大小是多少?我的理解是,只要数据适合内存,数据帧就应该可以,这对我来说不是问题。还有什么可能导致内存错误? 就上下文而言,我试图在《2007年消费者金融调查》中阅读ASCII格式(使用)和Stata格式(使用)。该文件的dta大小约为200MB,而ASCII的大小约为1.2GB,在Stata中打开该文件将告诉我,对于22,
作为一个长期的SAS用户,我正在探索切换到python和pandas。 然而,在今天运行一些测试时,我很惊讶python在尝试一个128MB的csv文件时内存耗尽。它大约有200,000行和200列,大部分是数字数据。 使用SAS,我可以将csv文件导入SAS数据集,并且它可以和我的硬盘一样大。 中有类似的内容吗? 我经常处理大文件,没有访问分布式计算网络的权限。