Ao ter um DataFrame do Pandas assim:
import pandas as pd
import numpy as np
df = pd.DataFrame({'today': [['a', 'b', 'c'], ['a', 'b'], ['b']],
'yesterday': [['a', 'b'], ['a'], ['a']]})
today yesterday
0 ['a', 'b', 'c'] ['a', 'b']
1 ['a', 'b'] ['a']
2 ['b'] ['a']
... etc
Porém, com cerca de 100.000 entradas, estou procurando encontrar as adições e remoções dessas listas nas duas colunas em uma linha.
É comparável a esta pergunta: Pandas: Como comparar colunas de listas em linhas em um DataFrame com Pandas (não para loop)? mas estou observando as diferenças, e o Pandas.apply
método parece não ser tão rápido para tantas entradas. Este é o código que estou usando no momento. Pandas.apply
com o numpy's setdiff1d
método:
additions = df.apply(lambda row: np.setdiff1d(row.today, row.yesterday), axis=1)
removals = df.apply(lambda row: np.setdiff1d(row.yesterday, row.today), axis=1)
Isso funciona bem, no entanto, leva cerca de um minuto para 120 000 entradas. Então, existe uma maneira mais rápida de conseguir isso?
Respostas:
Não tenho certeza sobre o desempenho, mas com a falta de uma solução melhor, isso pode se aplicar:
Remoções:
Aditivos:
fonte
applymap
, mas feliz que funcionou para você!fonte
Vou sugerir que você calcule
additions
eremovals
dentro da mesma aplicação.Gere um exemplo maior
Sua solução
Sua solução em uma única aplicação
Usando
set
A menos que suas listas sejam muito grandes, você pode evitar
numpy
Solução de @ r.ook
Se você está feliz por ter conjuntos em vez de listas como saída, você pode usar o código de @ r.ook
A solução de @Andreas K.
e você pode eventualmente adicionar
.apply(list)
para obter a mesma saídafonte
Aqui está um com a idéia de descarregar parte de computação para ferramentas NumPy vetorizadas. Reuniremos todos os dados em matrizes únicas para cada cabeçalho, executaremos toda a correspondência necessária no NumPy e, finalmente, voltaremos às entradas de linha necessárias. No NumPy que faz a parte de trabalho pesado, usaremos o hash com base nos IDs e IDs de cada grupo usando
np.searchsorted
. Também estamos usando números, pois esses são mais rápidos com o NumPy. A implementação seria algo parecido com isto -É possível uma otimização adicional nas etapas de cálculo
t_mask
ey_mask
, ondenp.searchsorted
poderia ser usado novamente.Também poderíamos usar uma atribuição de matriz simples como uma alternativa à
isin
etapa a ser obtidat_mask
ey_mask
, assim:fonte