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?

Niedakh
fonte
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)
Shravan
fonte
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)))
AlexG
fonte
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)
Surfista
fonte
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
chakuRak
fonte
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
mtd
fonte
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
Mark Horvath
fonte
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