在学习熊猫的过程中,我已经尝试了好几个月来找出这个问题的答案。我在日常工作中使用SAS,这是非常好的,因为它提供了非核心支持。然而,SAS作为一个软件是可怕的,原因还有很多。
有一天,我希望用python和熊猫取代SAS,但我目前缺乏大型数据集的核心外工作流。我说的不是需要分布式网络的“大数据”,而是文件太大,无法放入内存,但又小到足以放入硬盘。
我的第一个想法是使用HDFStore
在磁盘上保存大型数据集,只将我需要的片段拉入数据帧进行分析。其他人提到MongoDB是一种更易于使用的替代方案。我的问题是:
实现以下目标的最佳实践工作流有哪些:
现实世界中的例子将非常受欢迎,尤其是那些在“大数据”中使用熊猫的人。
编辑--我希望它如何工作的一个示例:
我正试图找到执行这些步骤的最佳实践方法。阅读关于pandas和pytables的链接似乎附加一个新的列可能是一个问题。
编辑——专门回答Jeff的问题:
我很少会向数据集添加行。我几乎总是会创建新的列(统计学/机器学习术语中的变量或特征)。
在这个问题两年后,现在有了一只“核心外”的熊猫:达斯克。它是优秀的!虽然它不支持熊猫的所有功能,但你可以用它走得很远。更新:在过去的两年里,它一直得到维护,并且有大量用户社区与Dask合作。
而现在,在问题提出四年后,Vaex中又出现了一个高性能的“核心外”熊猫。它“使用内存映射、零内存复制策略和惰性计算来获得最佳性能(无内存浪费)。”它可以处理数十亿行的数据集,而不将它们存储到内存中(甚至可以在次优硬件上进行分析)。
我认为上面的答案缺少一个我发现非常有用的简单方法。
当我有一个文件太大而无法加载到内存中时,我会将该文件分解为多个较小的文件(按行或列)
示例:如果有30天的交易数据大小约为30GB,我会每天将其拆分为一个大小约为1GB的文件。我随后分别处理每个文件,并在最后汇总结果
最大的优点之一是它允许并行处理文件(多线程或进程)
另一个优点是,文件操作(如示例中的添加/删除日期)可以通过常规shell命令完成,这在更高级/复杂的文件格式中是不可能的
这种方法并不涵盖所有场景,但在很多场景中都非常有用
我经常以这种方式使用数十GB的数据,例如,我在磁盘上有表,通过查询读取、创建数据并追加回来。
关于如何存储数据的一些建议,值得阅读文档和本线程的后期。
会影响你如何存储数据的细节,比如:
尽可能多地提供细节;我可以帮助你开发一个结构。
确保至少安装了0.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\u to\u 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'])
现在文件中有了所有的表(实际上,如果您愿意,可以将它们存储在单独的文件中,您可能需要将文件名添加到组映射中,但这可能不是必需的)。
以下是获取列和创建新列的方式:
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)
当您准备好进行后期处理时:
# 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)
关于数据列,实际上不需要定义任何数据列;它们允许您根据列对子选择行。例如,类似于:
store.select(group, where = ['field_1000=foo', 'field_1001>0'])
在最终报告生成阶段,您可能对它们最感兴趣(基本上,一个数据列与其他列是分离的,如果您定义了很多,这可能会在一定程度上影响效率)。
您可能还想:
让我知道,当你有问题!
在学习熊猫的过程中,我已经尝试了好几个月来找出这个问题的答案。我在日常工作中使用SAS,这是非常好的,因为它提供了非核心支持。然而,SAS作为一个软件是可怕的,原因还有很多。 有一天,我希望用python和pandas取代SAS的使用,但我目前缺乏大型数据集的核心外工作流。我说的不是需要分布式网络的“大数据”,而是文件太大而无法放入内存,但又太小而无法装入硬盘。 我的第一个想法是使用将大型数据集保
几个月来,我在学习熊猫的过程中,一直在努力想出这个问题的答案。我在日常工作中使用SAS,它的核心支持很棒。然而,SAS作为一个软件是可怕的,还有许多其他原因。 有一天我希望用python和pandas取代我对SAS的使用,但我目前缺少一个用于大型数据集的非核心工作流。我说的不是需要分布式网络的“大数据”,而是大到内存放不下但小到硬盘驱动器放不下的文件。 我的第一个想法是使用在磁盘上保存大型数据集,
问题内容: 在学习pandas的过程中,我试图迷惑了这个问题很多月。我在日常工作中使用SAS,这非常有用,因为它提供了核心支持。但是,由于许多其他原因,SAS作为一个软件还是很糟糕的。 有一天,我希望用python和pandas取代我对SAS的使用,但是我目前缺少大型数据集的核心工作流程。我并不是说需要分布式网络的“大数据”,而是文件太大而无法容纳在内存中,但文件又足够小而无法容纳在硬盘上。 我的
问题内容: 刚开始使用pandas和python。 我有一个工作表,已读入数据框并应用了前向填充(ffill)方法。 然后,我想创建一个包含两个工作表的Excel文档。 在应用填充方法之前,一个工作表将在数据框中包含数据,而在下一个工作表将应用了填充方法的数据框。 最终,我打算为数据框的特定列中的每个数据唯一实例创建一个工作表。 然后,我想对结果应用某些vba格式-但我不确定哪个dll或插件,或者
上面的问题是假设一周有7天。它试图计算每周有7天。我的数据是由(工作日)每日价格组成的,有时可能会因为市场因假期关闭而错过一周的几天。 我的问题是如何找到给定日期的一个月中的一周。注:我突出了“给定日期”,因为这个过程每天都在处理,所以任何展望到月底的答案都可能不起作用。 我的尝试是向前看,但不是最佳的: 如果你发现这个问题有任何问题,或者它是重复的,请告诉我。我已经寻找了一段时间的解决办法。
问题内容: 假设我有一个熊猫数据框: 我想计算数据框的列均值。 这很简单: 然后按列范围max(col)-min(col)。这又很容易: 现在,对于每个元素,我要减去其列的均值并除以其列的范围。我不确定该怎么做 任何帮助/指针将不胜感激。 问题答案: