Deque en Python Pandas

Estoy usando deque() Python para implementar un búfer circular simple:

 from collections import deque import numpy as np test_sequence = np.array(range(100)*2).reshape(100,2) mybuffer = deque(np.zeros(20).reshape((10, 2))) for i in test_sequence: mybuffer.popleft() mybuffer.append(i) do_something_on(mybuffer) 

Me preguntaba si hay una forma sencilla de obtener lo mismo en Pandas utilizando una Series (o DataFrame ). En otras palabras, ¿cómo puedo agregar de manera eficiente una sola fila al final y eliminar una sola fila al comienzo de una Series o un DataFrame ?

Edit: he intentado esto:

 myPandasBuffer = pd.DataFrame(columns=('A','B'), data=np.zeros(20).reshape((10, 2))) newpoint = pd.DataFrame(columns=('A','B'), data=np.array([[1,1]])) for i in test_sequence: newpoint[['A','B']] = i myPandasBuffer = pd.concat([myPandasBuffer.ix[1:],newpoint], ignore_index = True) do_something_on(myPandasBuffer) 

Pero es dolorosamente más lento que el método deque() .

Como señala Dorvak, los pandas no están diseñados para comportamientos de cola.

A continuación, he replicado la función de inserción simple de deque en marcos de datos de pandas, arreglos numpy y también en hdf5 usando el módulo h5py.

La función timeit revela (como era de esperar) que el módulo de colecciones es mucho más rápido, seguido de numpy y luego de pandas.

 from collections import deque import pandas as pd import numpy as np import h5py def insert_deque(test_sequence, buffer_deque): for item in test_sequence: buffer_deque.popleft() buffer_deque.append(item) return buffer_deque def insert_df(test_sequence, buffer_df): for item in test_sequence: buffer_df.iloc[0:-1,:] = buffer_df.iloc[1:,:].values buffer_df.iloc[-1] = item return buffer_df def insert_arraylike(test_sequence, buffer_arr): for item in test_sequence: buffer_arr[:-1] = buffer_arr[1:] buffer_arr[-1] = item return buffer_arr test_sequence = np.array(list(range(100))*2).reshape(100,2) # create buffer arrays nested_list = [[0]*2]*5 buffer_deque = deque(nested_list) buffer_df = pd.DataFrame(nested_list, columns=('A','B')) buffer_arr = np.array(nested_list) # calculate speed of each process in ipython print("deque : ") %timeit insert_deque(test_sequence, buffer_deque) print("pandas : ") %timeit insert_df(test_sequence, buffer_df) print("numpy array : ") %timeit insert_arraylike(test_sequence, buffer_arr) print("hdf5 with h5py : ") with h5py.File("h5py_test.h5", "w") as f: f["buffer_hdf5"] = np.array(nested_list) %timeit insert_arraylike(test_sequence, f["buffer_hdf5"]) 

Los resultados de% timeit:

deque: 34.1 µs por bucle

pandas: 48 ms por bucle

matriz numpy: 187 µs por bucle

hdf5 con h5py: 31.7 ms por bucle

Notas:

Mi método de corte de pandas fue solo un poco más rápido que el método de concat que aparece en la pregunta.

El formato hdf5 (a través de h5py) no mostró ninguna ventaja. Tampoco veo ninguna ventaja de HDFStore, como lo sugiere Andy.