Estou começando nos documentos do DataFrame do pandas aqui: http://pandas.pydata.org/pandas-docs/stable/dsintro.html
Gostaria de preencher iterativamente o DataFrame com valores em um tipo de cálculo de série temporal. Então, basicamente, eu gostaria de inicializar o DataFrame com as colunas A, B e as linhas de registro de data e hora, todas as 0 ou todas as NaN.
Eu adicionaria valores iniciais e examinaria esses dados calculando a nova linha da linha antes, digamos row[A][t] = row[A][t-1]+1
assim.
Atualmente, estou usando o código abaixo, mas acho que é meio feio e deve haver uma maneira de fazer isso com um DataFrame diretamente, ou apenas um modo melhor em geral. Nota: Estou 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
.append
pd e anexar uma lista? Eu sei que.append
nos pandas copia todo o conjunto de dados para um novo objeto; os pythons acrescentam funcionam de maneira diferente?Respostas:
Aqui estão algumas sugestões:
Use
date_range
para o índice:Nota: poderíamos criar um DataFrame (
NaN
s) vazio simplesmente escrevendo:Para fazer esses tipos de cálculos para os dados, use uma matriz numpy:
Portanto, podemos criar o DataFrame:
fonte
index
x0
dimensões (columns = []
) e anexar uma coluna a cada volta de um loop. Quero dizerdf[col_name] = pandas.Series([...])
em um loop percorrendo os nomes das colunas. No primeiro caso, não apenas a alocação de memória leva tempo, mas a substituição de NaNs por novos valores parece extremamente lenta.Se você simplesmente deseja criar um quadro de dados vazio e preenchê-lo com alguns quadros de dados recebidos posteriormente, tente o seguinte:
Neste exemplo, estou usando este documento do pandas para criar um novo quadro de dados e, em seguida, usando o acréscimo para gravar no newDF com dados do oldDF.
Se eu tiver que continuar anexando novos dados a este newDF de mais de um oldDFs, apenas uso um loop for para iterar sobre pandas.DataFrame.append ()
fonte
append
(e da mesma formaconcat
) copia o conjunto de dados completo para um novo objeto toda vez; portanto, a iteração e o acréscimo podem e causarão um grande impacto no desempenho. para obter mais informações, consulte: pandas.pydata.org/pandas-docs/stable/merging.htmlA maneira certa de criar um DataFrame
A maioria das respostas aqui mostrará como criar um DataFrame vazio e preenchê-lo, mas ninguém lhe dirá que é uma coisa ruim a se fazer.
Aqui está o meu conselho: espere até ter certeza de que possui todos os dados com os quais precisa trabalhar. Use uma lista para coletar seus dados e, em seguida, inicialize um DataFrame quando estiver pronto.
É sempre mais barato anexar a uma lista e criar um DataFrame de uma só vez do que criar um DataFrame vazio (ou um dos NaNs) e anexá-lo repetidamente. As listas também ocupam menos memória e são uma estrutura de dados muito mais leve para trabalhar , anexar e remover (se necessário).
A outra vantagem desse método é
dtypes
inferida automaticamente (em vez de atribuirobject
a todos eles).A última vantagem é que a
RangeIndex
é criada automaticamente para seus dados , portanto, é uma coisa a menos com que se preocupar (dê uma olhada nos métodosappend
e nosloc
métodos abaixo, você verá elementos nos dois que exigem o tratamento adequado do índice).Coisas que você NÃO deve fazer
append
ouconcat
dentro de um loopAqui está o maior erro que eu já vi dos iniciantes:
A memória é re-alocados para cada
append
ouconcat
operação que você tem. Junte isso a um loop e você terá uma operação de complexidade quadrática . Nadf.append
página do documento :O outro erro associado
df.append
é que os usuários tendem a esquecer o acréscimo não é uma função no local , portanto, o resultado deve ser atribuído novamente. Você também precisa se preocupar com os tipos:Lidar com colunas de objetos nunca é uma coisa boa, porque os pandas não podem vetorizar operações nessas colunas. Você precisará fazer isso para corrigi-lo:
loc
dentro de um loopEu também vi
loc
usado para acrescentar a um DataFrame que foi criado vazio:Como antes, você não pré-alocou a quantidade de memória necessária a cada vez; portanto, a memória é re-crescida cada vez que você cria uma nova linha . É tão ruim quanto
append
, e ainda mais feio.DataFrame vazio de NaNs
E então, está criando um DataFrame de NaNs, e todas as advertências associadas a ele.
Ele cria um DataFrame de colunas de objeto, como as outras.
O anexo ainda tem todos os problemas, conforme os métodos acima.
A prova está no pudim
A temporização desses métodos é a maneira mais rápida de ver o quanto eles diferem em termos de memória e utilidade.
Código de benchmarking para referência.
fonte
Inicializar quadro vazio com nomes de colunas
Adicionar um novo registro a um quadro
Você também pode querer passar um dicionário:
Anexe outro quadro ao seu quadro existente
Considerações de desempenho
Se você estiver adicionando linhas dentro de um loop, considere problemas de desempenho. Nos primeiros 1000 registros, o desempenho "my_df.loc" é melhor, mas gradualmente se torna mais lento, aumentando o número de registros no loop.
Se você planeja fazer finas dentro de um loop grande (digamos 10M de registros), é melhor usar uma mistura dessas duas; preencha um quadro de dados com iloc até que o tamanho fique em torno de 1000, depois anexe-o ao quadro de dados original e esvazie o quadro de dados temporário. Isso aumentaria seu desempenho em cerca de 10 vezes.
fonte
my_df = my_df.append(my_df2)
não funciona para mim, a menos que eu especifiqueignore_index=True
.Suponha um quadro de dados com 19 linhas
Manter a coluna A como constante
Mantendo a coluna b como uma variável dada por um loop
Você pode substituir o primeiro x
pd.Series([x], index = [x])
por qualquer valorfonte