Cómo crear una tabla dinámica en marcos de datos extremadamente grandes en Pandas
Necesito crear una tabla dinámica de 2000 columnas en alrededor de 30-50 millones de filas a partir de un conjunto de datos de alrededor de 60 millones de filas. Intenté girar en trozos de 100,000 filas, y eso funciona, pero cuando trato de recombinar los DataFrames haciendo un .append () seguido de .groupby ('someKey'). Sum (), toda mi memoria está ocupada y Python finalmente se bloquea.
¿Cómo puedo hacer un pivote en datos tan grandes con una cantidad limitada de RAM?
EDITAR: agregar código de muestra
El siguiente código incluye varias salidas de prueba en el camino, pero la última impresión es lo que realmente nos interesa. Tenga en cuenta que si cambiamos segMax a 3, en lugar de 4, el código producirá un falso positivo para la salida correcta. El problema principal es que si una entrada de envío no está en todos y cada uno de los fragmentos que mira la suma (wawa), no aparece en la salida.
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')