Criar um Pandas DataFrame vazio, e depois enchê-lo?

I'estou a partir dos documentos DataFrame dos pandas aqui: http://pandas.pydata.org/pandas-docs/stable/dsintro.html

I'gostaria de preencher iterativamente o DataFrame com valores em um tipo de cálculo de séries temporais. Então basicamente, I'gostaria de inicializar o DataFrame com as colunas A, B e linhas de timestamp, todas 0 ou todas as NaN.

I'd então adicione os valores iniciais e repasse esses dados calculando a nova linha da linha antes, diga row[A][t] = row[A][t-1]+1 ou assim.

I'estou atualmente usando o código como abaixo, mas eu sinto-o's meio feio e deve haver uma maneira de fazer isso com um DataFrame diretamente, ou apenas uma maneira melhor em geral. Nota: I'm usando o Python 2.7.

import datetime as dt
import pandas as pd
import scipy as s

if __name__ == '__main__':
    base = dt.datetime.today().date()
    dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
    dates.sort()

    valdict = {}
    symbols = ['A','B', 'C']
    for symb in symbols:
        valdict[symb] = pd.Series( s.zeros( len(dates)), dates )

    for thedate in dates:
        if thedate > dates[0]:
            for symb in valdict:
                valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]

    print valdict
Solução

Aqui's um par de sugestões:

Utilize date_range para o índice:

import datetime
import pandas as pd
import numpy as np

todays_date = datetime.datetime.now().date()
index = pd.date_range(todays_date-datetime.timedelta(10), periods=10, freq='D')

columns = ['A','B', 'C']

Note: poderíamos criar um DataFrame vazio (com NaNs) simplesmente escrevendo:

df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs

Para fazer estes tipos de cálculos para os dados, use uma matriz numérica:

data = np.array([np.arange(10)]*3).T

Assim, podemos criar o DataFrame:

In [10]: df = pd.DataFrame(data, index=index, columns=columns)

In [11]: df
Out[11]: 
            A  B  C
2012-11-29  0  0  0
2012-11-30  1  1  1
2012-12-01  2  2  2
2012-12-02  3  3  3
2012-12-03  4  4  4
2012-12-04  5  5  5
2012-12-05  6  6  6
2012-12-06  7  7  7
2012-12-07  8  8  8
2012-12-08  9  9  9
Comentários (7)

Se você quiser simplesmente criar um quadro de dados vazio e preenchê-lo com alguns quadros de dados recebidos mais tarde, tente isto:

Neste exemplo estou usando este documento pandas para criar um novo quadro de dados e depois usando anexar para escrever no novoDF com dados do antigoDF.


**Dêem uma olhadela nisto...

newDF = pd.DataFrame() #creates a new dataframe that's empty
newDF = newDF.append(oldDF, ignore_index = True) # ignoring index is optional
# try printing some data from newDF
print newDF.head() #again optional 
  • se eu tiver de continuar a anexar novos dados a este novoDF a partir de mais de um velhoDF, eu só uso um loop para iterar sobre pandas.DataFrame.append()
Comentários (3)

Se você quiser ter os nomes das suas colunas desde o início, use esta abordagem:

import pandas as pd

col_names =  ['A', 'B', 'C']
my_df  = pd.DataFrame(columns = col_names)
my_df

Se você quiser adicionar um registro ao dataframe, seria melhor usar:

my_df.loc[len(my_df)] = [2, 4, 5]

Também pode querer passar um dicionário:

my_dic = {'A':2, 'B':4, 'C':5}
my_df.loc[len(my_df)] = my_dic 

No entanto, se você quiser adicionar outro dataframe ao my_df faça o seguinte:

col_names =  ['A', 'B', 'C']
my_df2  = pd.DataFrame(columns = col_names)
my_df = my_df.append(my_df2)

Se você estiver adicionando linhas dentro de um loop, considere problemas de desempenho:
Para cerca de 1000 registos "my_df.loc" o desempenho é melhor, mas torna-se gradualmente mais lento ao aumentar o número de registos no loop.

Se você planeja fazer coisas dentro de um grande loop (digamos 10M records or so so):
Você está melhor usando uma mistura destes dois; preencha um dataframe com iloc até o tamanho chegar a cerca de 1000, depois junte-o ao dataframe original e esvazie o dataframe temporário. Isto aumentaria o seu desempenho em cerca de 10 vezes.

Comentários (0)