При использовании Pandas DataFrame, как это:
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
Но с примерно 100 000 записей я ищу, чтобы найти и удалить эти списки в двух столбцах построчно.
Это сравнимо с этим вопросом: Pandas: Как сравнивать столбцы списков по строкам в кадре данных с Pandas (не для цикла)? но я смотрю на различия, и Pandas.apply
метод, кажется, не такой быстрый для такого количества записей. Это код, который я сейчас использую. Pandas.apply
с numpy's setdiff1d
методом:
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)
Это прекрасно работает, однако для 120 000 записей требуется около минуты. Так есть ли более быстрый способ сделать это?
Ответы:
Не уверен насчет производительности, но из-за отсутствия лучшего решения это может быть применимо:
Удаления:
дополнения:
источник
applymap
, но рад, что она сработала для вас!источник
Я предложу вам посчитать
additions
и вremovals
пределах этого же подать заявку.Создайте пример большего
Ваше решение
Ваше решение по одной заявке
С помощью
set
Если ваши списки не очень большие, вы можете избежать
numpy
решение @ r.ook
Если вы довольны, что в качестве выходных данных вместо наборов используются списки, вы можете использовать код @ r.ook
Решение @Andreas K.
и вы можете в конечном итоге добавить,
.apply(list)
чтобы получить свой же выводисточник
Вот один из них с идеей разгрузки вычислительной части в векторизованные инструменты NumPy. Мы соберем все данные в отдельные массивы для каждого заголовка, выполним все необходимые сопоставления в NumPy и, наконец, вернемся к нужным элементам строки. На NumPy, который выполняет тяжелую часть, мы будем использовать хеширование на основе идентификаторов групп и идентификаторов внутри каждой группы
np.searchsorted
. Мы также используем числа, так как они быстрее с NumPy. Реализация будет выглядеть примерно так -Дальнейшая оптимизация возможна на этапах вычисления
t_mask
иy_mask
, гдеnp.searchsorted
может использоваться снова.Мы также могли бы использовать простое присвоение массива в качестве альтернативы
isin
шагу, чтобы получитьt_mask
иy_mask
, как это так -источник