【发布时间】:2015-06-08 23:31:52
【问题描述】:
我需要从大约 6000 万行的数据集中创建一个包含 2000 列、大约 30-5000 万行的数据透视表。我尝试过以 100,000 行为一组进行旋转,这很有效,但是当我尝试通过执行 .append() 和 .groupby('someKey').sum() 来重新组合 DataFrame 时,我的所有内存都被占用了而python最终崩溃了。
如何使用有限的 RAM 对这么大的数据进行数据透视?
编辑:添加示例代码
下面的代码包括各种测试输出,但最后的打印是我们真正感兴趣的。请注意,如果我们将 segMax 更改为 3,而不是 4,代码将产生正确输出的误报.主要问题是如果一个 shippingid 条目不在 sum(wawa) 所查看的每个块中,它就不会显示在输出中。
import pandas as pd
import numpy as np
import random
from pandas.io.pytables import *
import os
pd.set_option('io.hdf.default_format','table')
# create a small dataframe to simulate the real data.
def loadFrame():
frame = pd.DataFrame()
frame['shipmentid']=[1,2,3,1,2,3,1,2,3] #evenly distributing shipmentid values for testing purposes
frame['qty']= np.random.randint(1,5,9) #random quantity is ok for this test
frame['catid'] = np.random.randint(1,5,9) #random category is ok for this test
return frame
def pivotSegment(segmentNumber,passedFrame):
segmentSize = 3 #take 3 rows at a time
frame = passedFrame[(segmentNumber*segmentSize):(segmentNumber*segmentSize + segmentSize)] #slice the input DF
# ensure that all chunks are identically formatted after the pivot by appending a dummy DF with all possible category values
span = pd.DataFrame()
span['catid'] = range(1,5+1)
span['shipmentid']=1
span['qty']=0
frame = frame.append(span)
return frame.pivot_table(['qty'],index=['shipmentid'],columns='catid', \
aggfunc='sum',fill_value=0).reset_index()
def createStore():
store = pd.HDFStore('testdata.h5')
return store
segMin = 0
segMax = 4
store = createStore()
frame = loadFrame()
print('Printing Frame')
print(frame)
print(frame.info())
for i in range(segMin,segMax):
segment = pivotSegment(i,frame)
store.append('data',frame[(i*3):(i*3 + 3)])
store.append('pivotedData',segment)
print('\nPrinting Store')
print(store)
print('\nPrinting Store: data')
print(store['data'])
print('\nPrinting Store: pivotedData')
print(store['pivotedData'])
print('**************')
print(store['pivotedData'].set_index('shipmentid').groupby('shipmentid',level=0).sum())
print('**************')
print('$$$')
for df in store.select('pivotedData',chunksize=3):
print(df.set_index('shipmentid').groupby('shipmentid',level=0).sum())
print('$$$')
store['pivotedAndSummed'] = sum((df.set_index('shipmentid').groupby('shipmentid',level=0).sum() for df in store.select('pivotedData',chunksize=3)))
print('\nPrinting Store: pivotedAndSummed')
print(store['pivotedAndSummed'])
store.close()
os.remove('testdata.h5')
print('closed')
【问题讨论】:
-
值得注意的是,不仅python会崩溃,它还会导致整个计算机崩溃。显然不是我可以让它煮几天的情况。
-
根据数据的性质,您可能想尝试使用sparse DataFrames。它可以为您节省大量内存。
-
由于我的 shippingid 值都是数字,我现在正在尝试从 pivotedData 表中手动选择一个 shippingid 的整数值,从 0 增加到 500 万左右,然后执行sum() 结果,并将其附加到存储中的结果表中。但是,每次选择都需要很长时间,尤其是当特定的shippingid 不存在条目时。将继续使用压缩设置,看看是否有帮助。
-
为什么不使用 RDMS 来聚合您的数据集? SQL 引擎旨在存储数百万条记录并按组处理 Sum() 等基本处理。正如您的枢轴所指出的那样,我假设是两个字节大小的字段(ids)和一个整数(qty)字段,临时数据库表不应该太广泛而无法存储和查询。考虑在 SQL Server、Oracle、MySQL、PostgreSQL 或任何其他内部进行聚合,并将结果传递给 Python dataframe。
-
数据来自哪里?数据库(如果有,是哪个?)、.csv 文件、HDF5 等
标签: python python-3.x pandas pivot-table