Manipulei alguns dados usando pandas e agora quero executar um salvamento em lote no banco de dados. Isso requer que eu converta o quadro de dados em uma matriz de tuplas, com cada tupla correspondendo a uma "linha" do quadro de dados.
Meu DataFrame se parece com:
In [182]: data_set
Out[182]:
index data_date data_1 data_2
0 14303 2012-02-17 24.75 25.03
1 12009 2012-02-16 25.00 25.07
2 11830 2012-02-15 24.99 25.15
3 6274 2012-02-14 24.68 25.05
4 2302 2012-02-13 24.62 24.77
5 14085 2012-02-10 24.38 24.61
Eu quero convertê-lo em uma matriz de tuplas como:
[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]
Alguma sugestão de como posso fazer isso com eficiência?
list(df.itertuples(index=False, name=None))
df.to_records(index=False)
e uma lista de ditados:df.to_dict('records')
Respostas:
E se:
para pandas <0,24 use
fonte
.itertuples
, que será mais eficiente do que obter os valores como uma matriz e transformá-los em uma tupla.A partir de 17.1, o acima retornará uma lista de nomeados .
Se você quiser uma lista de tuplas comuns, passe
name=None
como argumento:fonte
tuple
s normais no seuzip
iterador (em vez denamedtuple
s), chame:data_set.itertuples(index=False, name=None)
itertuples
é lento . Evite se possível. Para loops (como mostrado na resposta aceita) geralmente é mais rápido nesses casos.Uma maneira genérica:
fonte
data_set.to_records(index=False).tolist()
melhor?Motivação
Muitos conjuntos de dados são grandes o suficiente para que possamos nos preocupar com velocidade / eficiência. Então, eu ofereço esta solução nesse espírito. Acontece também ser sucinto.
Para fins de comparação, vamos soltar a
index
colunaSolução
vou propor o uso
zip
emap
Também é flexível se quisermos lidar com um subconjunto específico de colunas. Vamos assumir que as colunas que já exibimos são o subconjunto que queremos.
O que é mais rápido?
O resultado
records
é mais rápido, seguido de convergência assintoticamentezipmap
eiter_tuples
Vou usar uma biblioteca
simple_benchmarks
que recebi deste postConfira os resultados
fonte
Aqui está uma abordagem vetorizada (assumindo que o quadro
data_set
de dados seja definido como alternativadf
) que retorna alist
detuples
como mostrado:produz:
A idéia de definir a coluna de data e hora como o eixo do índice é ajudar na conversão do
Timestamp
valor para odatetime.datetime
formato correspondente equivalente, usando oconvert_datetime64
argumento noDF.to_records
qual o faz para umDateTimeIndex
quadro de dados.Isso retorna um
recarray
que poderia ser feito para retornar umlist
uso.tolist
Uma solução mais generalizada, dependendo do caso de uso, seria:
fonte
A maneira mais eficiente e fácil:
Você pode filtrar as colunas necessárias antes desta chamada.
fonte
Esta resposta não adiciona respostas que ainda não foram discutidas, mas aqui estão alguns resultados de velocidade. Eu acho que isso deve resolver as questões que surgiram nos comentários. Todos eles parecem O (n) , com base nesses três valores.
TL; DR :
tuples = list(df.itertuples(index=False, name=None))
etuples = list(zip(*[df[c].values.tolist() for c in df]))
estão empatados para o mais rápido.Fiz um teste rápido de velocidade nos resultados para três sugestões aqui:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
tuples = [tuple(x) for x in df.values]
name=None
sugestão de @Axel:tuples = list(df.itertuples(index=False, name=None))
Tamanho pequeno:
Dá:
Maior:
Dá:
Tanta paciência quanto eu tenho:
Dá:
A versão zip e a versão iteruples estão dentro dos intervalos de confiança entre si. Eu suspeito que eles estão fazendo a mesma coisa sob o capô.
Esses testes de velocidade provavelmente são irrelevantes. Aumentar os limites da memória do meu computador não leva muito tempo, e você realmente não deveria fazer isso em um grande conjunto de dados. Trabalhar com essas tuplas depois de fazer isso será realmente ineficiente. É improvável que seja um grande gargalo no seu código, então fique com a versão que você acha mais legível.
fonte
[*zip(*map(df.get, df))]
há algum tempo agora. Enfim, achei que você acharia interessante.fonte
Alterando a lista de quadros de dados em uma lista de tuplas.
fonte
Maneira mais pitônica:
fonte
map()
é notoriamente antitônico.