几个月来,我一直在努力想出这个问题的答案,同时学习熊猫。我的日常工作使用SAS,这是很好的,因为它的核心支持。然而,SAS作为一个软件是可怕的,因为许多其他原因。
有一天,我希望用蟒蛇和熊猫来代替我对SAS的使用,但我目前缺乏一个大型数据集的核心工作流程。我说的不是需要分布式网络的“大数据”,而是文件太大,无法容纳内存,但足够小到适合于硬盘驱动器。
我的第一个想法是使用HDFStore
在磁盘上保存大型数据集,并只将所需的数据块拉到数据文件中进行分析。其他人提到MongoDB是一种更容易使用的替代方案。我的问题是:
完成以下工作的最佳实践工作流是什么?
现实世界的例子将是非常感谢的,特别是谁使用大熊猫的“大数据”。
编辑--一个我希望它如何工作的例子:
我正在努力寻找一种最佳实践的方法来执行这些步骤。阅读有关熊猫和比目表的链接,似乎增加一个新的专栏可能是一个问题。
编辑--专门回答杰夫的问题:
if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B'
。这些操作的结果是为数据集中的每条记录创建一个新列。我很少会将行添加到数据集中。我几乎总是创建新的列(统计/机器学习术语中的变量或特性)。
发布于 2013-01-10 22:57:22
我经常以这种方式使用数十in的数据,例如,我在磁盘上有通过查询读取的表、创建数据和追加数据。
关于如何存储数据的几个建议,值得阅读医生们和在这个线程的后期。
将影响数据存储方式的详细信息,如:
尽可能多地详细说明,我可以帮助你发展一个结构。
解决方案
确保安装了。
阅读逐块迭代文件和多表查询。
由于pytable被优化为按行操作(这就是您所查询的),我们将为每一组字段创建一个表。这样就可以很容易地选择一小组字段(这将与一个大表一起工作,但这样做更有效。)我想我将来也许能解决这个问题.无论如何,这更直观):
(以下是伪码。)
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,您实际上不需要定义ANY data_columns;它们允许您根据列对行进行子选择。例如,类似:
store.select(group, where = ['field_1000=foo', 'field_1001>0'])
在最后的报表生成阶段,它们可能是您最感兴趣的(从本质上说,数据列与其他列是分离的,如果定义了很多,这可能会对效率产生一定的影响)。
你也可能想:
你有问题时告诉我!
发布于 2013-12-19 19:46:48
我认为上面的答案缺少一个简单的方法,我发现这是非常有用的。
当文件太大,无法在内存中加载时,我会将文件分解为多个较小的文件(行或科尔)。
例句:如果30天的交易数据是30 1GB大小的,我每天把它分解成一个1GB大小的文件。随后,我分别处理每个文件,并在最后聚合结果。
最大的优点之一是它允许并行处理文件(多个线程或进程)。
另一个优点是文件操作(比如在示例中添加/删除日期)可以通过常规的shell命令来完成,这在更高级/复杂的文件格式中是不可能的。
这种方法并不涵盖所有的场景,但在许多场景中非常有用。
发布于 2016-03-23 20:30:53
在这个问题两年后,现在出现了一种“核心外”大熊猫:达斯克。太棒了!虽然它不支持所有的熊猫功能,但你可以用它做更多的事情。更新:在过去两年中,它一直得到维护,并且有大量的用户社区与Dask合作。
而现在,四年后的问题,有另一个高性能的‘核外’熊猫在瓦埃克斯。它“使用内存映射、零内存复制策略和延迟计算以获得最佳性能(没有内存浪费)”。它可以处理数十亿行的数据集,并且不将它们存储到内存中(甚至可以对次优硬件进行分析)。
https://stackoverflow.com/questions/14262433
复制相似问题