Eu estive pensando ... Se eu estiver lendo, digamos, um arquivo csv de 400 MB em um dataframe do pandas (usando read_csv ou read_table), há alguma maneira de estimar quanta memória isso vai precisar? Só tentando ter uma ideia melhor dos frames de dados e da memória ...
125
top
e, em seguida,Shift + M
para classificar o meu uso de memória.x=df.loc[[]]
leva0.1
segundos para ser calculado (para extrair zero linhas) e, além disso, leva centenas de megabytes de memória, assim como o dataframe original, provavelmente por causa de alguma cópia embaixo.Respostas:
df.memory_usage()
retornará quanto cada coluna ocupa:Para incluir índices, passe
index=True
.Portanto, para obter o consumo geral de memória:
Além disso, a passagem
deep=True
permitirá um relatório de uso de memória mais preciso, que contabiliza o uso total dos objetos contidos.Isso ocorre porque o uso de memória não inclui a memória consumida por elementos que não são componentes da matriz if
deep=False
(caso padrão).fonte
deep=True
deep=True
memory_usage()
retorna o uso de memória em bytes (como você esperaria).Aqui está uma comparação dos diferentes métodos -
sys.getsizeof(df)
é o mais simples.Para este exemplo,
df
é um dataframe com 814 linhas, 11 colunas (2 ints, 9 objetos) - lido a partir de um shapefile de 427kbsys.getsizeof (df)
df.memory_usage ()
df.info ()
Imprime informações do dataframe no stdout. Tecnicamente, são kibibytes (KiB), não kilobytes - como diz a docstring, "O uso da memória é mostrado em unidades legíveis (representação de base 2)." Portanto, obter bytes seria multiplicado por 1024, por exemplo, 451,6 KiB = 462.438 bytes.
fonte
g
código acima se refere?df.info(memory_usage="deep")
, ele retorna "392,6 MB", enquantosys.getsizeof(df)
edf.memory_usage(index=True, deep=True).sum()
ambos retornam aproximadamente "411718016" (~ 411 MB). Você pode explicar por que os 3 resultados não são consistentes? obrigadodf.memory_usage(deep=True).sum()
retorna quase o mesmo comdf.memory_usage(index=True, deep=True).sum()
. no meu caso,index
não ocupa muita memória. Curiosamente, descobri que411718016/1024/1024 = 392.6
, portanto,df.info(memory_usage="deep")
pode usar2^10
para converter byte em MB , o que me deixa confuso. Obrigado pela sua ajuda de qualquer maneira: D.df.info
está retornando mebibytes (2 ^ 10), não megabytes (10 ^ 6) - corrigirá a resposta.Pensei em trazer mais alguns dados para a discussão.
Executei uma série de testes sobre esse problema.
Usando o
resource
pacote python , consegui o uso de memória do meu processo.E escrevendo o csv em um
StringIO
buffer, eu poderia facilmente medir o tamanho dele em bytes.Fiz dois experimentos, cada um criando 20 dataframes de tamanhos crescentes entre 10.000 e 1.000.000 de linhas. Ambos com 10 colunas.
No primeiro experimento, usei apenas flutuadores em meu conjunto de dados.
É assim que a memória aumentou em comparação ao arquivo csv em função do número de linhas. (Tamanho em megabytes)
No segundo experimento, tive a mesma abordagem, mas os dados no conjunto de dados consistiam em apenas sequências curtas.
Parece que a relação entre o tamanho do csv e o tamanho do dataframe pode variar bastante, mas o tamanho na memória será sempre maior por um fator de 2-3 (para os tamanhos de quadro neste experimento)
Eu adoraria completar esta resposta com mais experimentos, por favor, comente se você quiser que eu tente algo especial.
fonte
Você tem que fazer isso ao contrário.
Tecnicamente, a memória é sobre isso (que inclui os índices)
Portanto, 168 MB de memória com um arquivo de 400 MB, 1 milhão de linhas de 20 colunas flutuantes
MUITO mais compacto quando escrito como um arquivo HDF5 binário
Os dados eram aleatórios, então a compressão não ajuda muito
fonte
read_csv
?iotop
liketop
/htop
para assistir (em tempo real) o desempenho de IO.nbytes
será uma estimativa grosseira se você tiver, por exemplo, strings em um dataframe.Se você conhece os
dtype
s do seu array, então pode calcular diretamente o número de bytes necessários para armazenar seus dados + alguns para os próprios objetos Python. Um atributo útil dosnumpy
arrays énbytes
. Você pode obter o número de bytes dos arrays em um pandasDataFrame
fazendoobject
Arrays dtype armazenam 8 bytes por objeto (arrays dtype de objetos armazenam um ponteiro para um opacoPyObject
), então se você tem strings em seu csv você precisa levar em consideração queread_csv
irá transformá-los emobject
arrays dtype e ajustar seus cálculos de acordo.EDITAR:
Consulte a
numpy
página de tipos escalares para obter mais detalhes sobre oobject
dtype
. Visto que apenas uma referência é armazenada, você também precisa levar em consideração o tamanho do objeto no array. Como diz a página, os arrays de objetos são um tanto semelhantes aoslist
objetos Python .fonte
Sim existe. O Pandas irá armazenar seus dados em
ndarray
estruturas numpy bidimensionais agrupando-os por dtypes.ndarray
é basicamente uma matriz de dados C bruta com um pequeno cabeçalho. Assim, você pode estimar seu tamanho simplesmente multiplicando o tamanho dodtype
que contém pelas dimensões da matriz.Por exemplo: se você tiver 1000 linhas com 2
np.int32
e 5np.float64
colunas, seu DataFrame terá umanp.int32
matriz 2x1000 e umanp.float64
matriz 5x1000 que é:4 bytes * 2 * 1000 + 8 bytes * 5 * 1000 = 48000 bytes
fonte
DataFrame
?pandas
tem uma implementação muito eficiente doread_table
no Cython (é muito melhor do que o loadtxt do numpy), então presumo que ele analisa e armazena os dados diretamente nondarray
.Isso eu acredito que dá o tamanho na memória de qualquer objeto em python. Os internos precisam ser verificados em relação aos pandas e entorpecidos
fonte