Tworzenie ramki danych pandy wypełnionej zerami

105

Jaki jest najlepszy sposób na utworzenie ramki danych pandy wypełnionej zerami o danym rozmiarze?

Używałem:

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

Czy jest lepszy sposób, aby to zrobić?

niedakh
źródło
1
Nie, nie przychodzi mi do głowy żadna istotna poprawa.
Dan Allan,
Otrzymuję błąd pamięci na np.zeros, ponieważ dane to duży zestaw. Jakieś wskazówki, co mogę zrobić? Nie mam żadnego innego wyjścia poza „MemoryError”. Mam 100 GB pamięci RAM, a dane mają tylko 20 GB, ale nadal zawodzą. Nie mam pojęcia, jak to debugować, 64-bitowy serwer Ubuntu. Trochę googlowałem, ale wszyscy mówią - podziel na kawałki, ale tych danych nie można podzielić.
niedakh
Czy możesz po prostu pracować data? Dlaczego musisz stworzyć inną strukturę, aby ją utrzymać?
Phillip Cloud,

Odpowiedzi:

144

Możesz spróbować tego:

d = pd.DataFrame(0, index=np.arange(len(data)), columns=feature_list)
Shravan
źródło
2
Testowanie tego, co znalazłem, %timeit temp = np.zeros((10, 11)); d = pd.DataFrame(temp, columns = ['col1', 'col2',...'col11'])zajmuje 156 nas. Ale %timeit d = pd.DataFrame(0, index = np.arange(10), columns = ['col1', 'col2',...'col11'])zabiera nam 171. Dziwię się, że nie jest szybciej.
emschorsch
3
Zauważ, że możesz napotkać problem z int / float, jeśli d.set_value(params)po zainicjowaniu będziesz robił coś takiego, daby zawierało 0. Łatwo naprawić to: d = pd.DataFrame(0.0, index=np.arange(len(data)), columns=feature_list).
ximiki
31

Moim zdaniem najlepiej zrobić to z numpy

import numpy as np
import pandas as pd
d = pd.DataFrame(np.zeros((N_rows, N_cols)))
AlexG
źródło
1
Kiedy zrobiłem to w ten sposób, nie mogłem zmienić wartości „0”. TypeError: 'numpy.float64' object does not support item assignment
RightmireM
@RightmireM Jak dokładnie próbujesz je zmienić? Masz rację, typ danych tonp.float64
AlexG
11

Podobny do @Shravan, ale bez użycia numpy:

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

Wtedy możesz z nim zrobić, co chcesz:

post_instantiation_fcn = lambda x: str(x)
df_ready_for_whatever = df_0.applymap(post_instantiation_fcn)
Jeździec fal
źródło
8

Jeśli chcesz, aby nowa ramka danych miała ten sam indeks i kolumny, co istniejąca ramka danych, możesz po prostu pomnożyć istniejącą ramkę danych przez zero:

df_zeros = df * 0
chakuRak
źródło
2
Należy pamiętać, że wszędzie tam, gdzie df zawiera NaN, zamiast zer otrzymasz NaN.
kadee
1

Jeśli masz już ramkę danych, jest to najszybszy sposób:

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

Porównać do:

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
źródło
1

Zakładając, że mamy szablon DataFrame, który chciałoby się skopiować z zerowymi wartościami wypełnionymi tutaj ...

Jeśli w zestawie danych nie ma żadnych NaN, pomnożenie przez zero może być znacznie szybsze:

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

Ulepszenie zależy od rozmiaru DataFrame, ale nigdy nie było wolniej.

I po prostu do cholery:

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

Ale:

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

EDYTOWAĆ!!!

Zakładając, że masz ramkę wykorzystującą float64, będzie to najszybsze z ogromnym marginesem! Jest również w stanie wygenerować dowolną wartość, zastępując 0,0 na żądany numer wypełnienia.

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

W zależności od gustu można zdefiniować zewnętrznie nan i zrobić ogólne rozwiązanie, niezależnie od konkretnego typu spławika:

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
źródło
1
Jest to zdecydowanie najbardziej wyczerpująca odpowiedź na czas, chociaż w przypadku PO wydaje się, że problemem były wymagania pamięci, a nie szybkość ... Nawiasem mówiąc, w moim systemie dwie pierwsze sugestie, które napisałeś, dają ten sam czas (Pandy 0.20.3 ), więc być może nastąpiły pewne zmiany.
Moot