Criando um quadro de dados do pandas preenchido com zero


103

Qual é a melhor maneira de criar um quadro de dados pandas preenchido com zero de um determinado tamanho?

Eu tenho usado:

zero_data = np.zeros(shape=(len(data),len(feature_list)))
d = pd.DataFrame(zero_data, columns=feature_list)

Há uma melhor forma de fazê-lo?


1
Não, não consigo pensar em nenhuma melhoria substancial nisso.
Dan Allan,

Estou recebendo um erro de memória em np.zeros, pois os dados são um grande conjunto. Alguma dica sobre o que posso fazer? Não recebi outra saída além de "MemoryError". Tenho 100 GB de RAM e os dados têm apenas 20 GB, mas ainda falham. Não tenho ideia de como depurá-lo, servidor ubuntu de 64 bits. Pesquisei um pouco no Google, mas todo mundo diz - divida em pedaços, mas esses dados não podem ser divididos.
niedakh,

Você pode apenas trabalhar data? Por que você precisa criar outra estrutura para segurá-lo?
Phillip Cloud de

Respostas:


138

Você pode tentar isto:

d = pd.DataFrame(0, index=np.arange(len(data)), columns=feature_list)

2
O teste que eu acho %timeit temp = np.zeros((10, 11)); d = pd.DataFrame(temp, columns = ['col1', 'col2',...'col11'])leva 156 nós. Mas %timeit d = pd.DataFrame(0, index = np.arange(10), columns = ['col1', 'col2',...'col11'])leva 171 nós. Estou surpreso que não seja mais rápido.
emschorsch

3
Observe que você pode encontrar o problema int / float se for fazer algo como d.set_value(params)depois de inicializar dpara conter 0's. Um reparo fácil é: d = pd.DataFrame(0.0, index=np.arange(len(data)), columns=feature_list).
ximiki

29

É melhor fazer isso com numpy, na minha opinião

import numpy as np
import pandas as pd
d = pd.DataFrame(np.zeros((N_rows, N_cols)))

1
Quando fiz assim, não consegui alterar os valores "0". TypeError: 'numpy.float64' object does not support item assignment
RightmireM

@RightmireM Como exatamente você está tentando alterá-los? Você está correto, o tipo de dados énp.float64
AlexG

11

Semelhante a @Shravan, mas sem o uso de numpy:

  height = 10
  width = 20
  df_0 = pd.DataFrame(0, index=range(height), columns=range(width))

Então você pode fazer o que quiser com ele:

post_instantiation_fcn = lambda x: str(x)
df_ready_for_whatever = df_0.applymap(post_instantiation_fcn)

8

Se quiser que o novo quadro de dados tenha o mesmo índice e colunas de um quadro de dados existente, basta multiplicar o quadro de dados existente por zero:

df_zeros = df * 0

2
Esteja ciente de que você obterá NaNs em vez de zeros sempre que df contiver NaNs.
kadee

1

Se você já tem um dataframe, esta é a maneira mais rápida:

In [1]: columns = ["col{}".format(i) for i in range(10)]
In [2]: orig_df = pd.DataFrame(np.ones((10, 10)), columns=columns)
In [3]: %timeit d = pd.DataFrame(np.zeros_like(orig_df), index=orig_df.index, columns=orig_df.columns)
10000 loops, best of 3: 60.2 µs per loop

Comparado a:

In [4]: %timeit d = pd.DataFrame(0, index = np.arange(10), columns=columns)
10000 loops, best of 3: 110 µs per loop

In [5]: temp = np.zeros((10, 10))
In [6]: %timeit d = pd.DataFrame(temp, columns=columns)
10000 loops, best of 3: 95.7 µs per loop

1

Supondo que haja um modelo de DataFrame, qual gostaria de copiar com valores zero preenchidos aqui ...

Se você não tem NaNs em seu conjunto de dados, multiplicar por zero pode ser significativamente mais rápido:

In [19]: columns = ["col{}".format(i) for i in xrange(3000)]                                                                                       

In [20]: indices = xrange(2000)

In [21]: orig_df = pd.DataFrame(42.0, index=indices, columns=columns)

In [22]: %timeit d = pd.DataFrame(np.zeros_like(orig_df), index=orig_df.index, columns=orig_df.columns)
100 loops, best of 3: 12.6 ms per loop

In [23]: %timeit d = orig_df * 0.0
100 loops, best of 3: 7.17 ms per loop

A melhoria depende do tamanho do DataFrame, mas nunca o achei mais lento.

E só pra cacete:

In [24]: %timeit d = orig_df * 0.0 + 1.0
100 loops, best of 3: 13.6 ms per loop

In [25]: %timeit d = pd.eval('orig_df * 0.0 + 1.0')
100 loops, best of 3: 8.36 ms per loop

Mas:

In [24]: %timeit d = orig_df.copy()
10 loops, best of 3: 24 ms per loop

EDITAR!!!

Supondo que você tenha um quadro usando float64, este será o mais rápido por uma margem enorme! Ele também é capaz de gerar qualquer valor, substituindo 0,0 para o número de preenchimento desejado.

In [23]: %timeit d = pd.eval('orig_df > 1.7976931348623157e+308 + 0.0')
100 loops, best of 3: 3.68 ms per loop

Dependendo do gosto, pode-se definir nan externamente e fazer uma solução geral, independentemente do tipo de flutuador particular:

In [39]: nan = np.nan
In [40]: %timeit d = pd.eval('orig_df > nan + 0.0')
100 loops, best of 3: 4.39 ms per loop

1
Esta é definitivamente a resposta mais abrangente sobre o tempo, embora para o OP pareça que os requisitos de memória eram o problema e não a velocidade ... A propósito, no meu sistema as duas primeiras sugestões que você escreveu dão o mesmo tempo (Pandas 0.20.3 ), então talvez tenha havido algumas mudanças.
Moot de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.