У меня есть пандас, в котором значения столбцов существуют в виде списков. Каждый список имеет несколько элементов, и один элемент может существовать в нескольких строках. Пример кадра данных:
X = pd.DataFrame([(1,['a','b','c']),(2,['a','b']),(3,['c','d'])],columns=['A','B'])
X =
A B
0 1 [a, b, c]
1 2 [a, b]
2 3 [c, d]
Я хочу найти все строки, то есть индексы данных, соответствующие элементам в списках, и создать из него словарь. Не обращайте внимания на колонку A здесь, так как колонка B представляет интерес! Таким образом, элемент 'a' находится в индексе 0,1, что дает {'a': [0,1]}. Решение для этого примера кадра данных:
Y = {'a':[0,1],'b':[0,1],'c':[0,2],'d':[2]}
Я написал код, который отлично работает, и я могу получить результат. Моя проблема больше связана со скоростью вычислений. Мой фактический фрейм данных имеет около 350 000 строк, а списки в столбце «B» могут содержать до 1000 элементов. Но в настоящее время код работает в течение нескольких часов! Мне было интересно, является ли мое решение очень неэффективным.
Любая помощь с более быстрым и эффективным способом будет по-настоящему оценена!
Вот мой код решения:
import itertools
import pandas as pd
X = pd.DataFrame([(1,['a','b','c']),(2,['a','b']),(3,['c','d'])],columns=['A','B'])
B_dict = []
for idx,val in X.iterrows():
B = val['B']
B_dict.append(dict(zip(B,[[idx]]*len(B))))
B_dict = [{k: list(itertools.chain.from_iterable(list(filter(None.__ne__, [d.get(k) for d in B_dict])))) for k in set().union(*B_dict)}]
print ('Result:',B_dict[0])
выход
Result: {'d': [2], 'c': [0, 2], 'b': [0, 1], 'a': [0, 1]}
Код для последней строки в цикле for был заимствован отсюда: Объединить значения одних и тех же ключей в списке диктов и удалить значение None из списка без удаления значения 0