Как объединить несколько списков кортежей из фрейма данных в один словарь?

#python #list #dataframe #dictionary #tuples

#python #Список #фрейм данных #словарь #кортежи

Вопрос:

Я огляделся и не смог объединить фрагменты информации в разных частичных решениях, которые я нашел, так что вот проблема:

Анализируя обзоры Amazon, я организовал данные в dataframe и создал столбец с количеством каждого слова, используемого в каждом обзоре. Итак, у меня есть столбец, в котором каждая строка содержит список кортежей.

Я ищу эффективный способ (мой набор данных содержит миллионы обзоров) объединить все эти списки кортежей в один словарь. В идеале, этот словарь уже будет содержать вес каждого слова (который является количеством голосов их соответствующего обзора), хотя я могу выяснить это позже, если это слишком много, чтобы спрашивать.

Вот пример:

 df['words'] = [('thank', 2),('you',2),('this',5)],
              [('interesting',1),('this',3)],
              [('thank,3),('me',2),('later',2)],
              [('me',2),('interesting',1)],
              [('thank',2),('you',1),('again',1)]
df['votes'] = 10
               5
               2
               1
               1
  

Желаемый результат (или как вложенный dict) — 1-е число представляет собой сумму частот, присутствующих в кортежах, а 2-е — это сумма весов, расположенных в столбце «голоса»:

 top_words = {'this':(8,15),'thank':(7,13),'me':(4,3),'you':(3,11),'interesting':(2,6),'later':(2,2),'again':(1,1)}
  

Я пробовал dict(zip(* df[words]) и некоторые другие подобные методы, но всегда получаю ошибки (добавленная взвешенная информация была бы потрясающей, но пока не является строго необходимой). У меня такое чувство, что ответ довольно прост, но он ускользает от меня.

Предложения?

Комментарии:

1. опубликуйте образец фрейма данных

Ответ №1:

Для этого вы можете использовать функцию reduce и numpy.

 df = {}
df['words'] = [[('thank', 2),('you',2),('this',5)],
              [('interesting',1),('this',3)],
              [('thank',3),('me',2),('later',2)],
              [('me',2),('interesting',1)],
              [('thank',2),('you',1),('again',1)]]
df['votes'] = [10,5,2,1,1]

from functools import reduce
import numpy as np

data = dict(zip(df['votes'], df['words']))
'''
{
 1: [('thank', 2), ('you', 1), ('again', 1)],
 2: [('thank', 3), ('me', 2), ('later', 2)],
 5: [('interesting', 1), ('this', 3)],
 10: [('thank', 2), ('you', 2), ('this', 5)]
}
'''

def add(a, x, data):
  for word in data[x]:
    if word[0] not in list(a.keys()):
      a[word[0]] = (0, 0)
    a[word[0]] = tuple(np.add(a[word[0]], (word[1], x)))
  return a

output = reduce(lambda a, x: add(a, x, data), data, {})

'''
{
 'again': (1, 1),
 'interesting': (1, 5),
 'later': (2, 2),
 'me': (2, 2),
 'thank': (7, 13),
 'this': (8, 15),
 'you': (3, 11)
}
'''
  

Я использовал dict(zip(df['votes'], df['words'])) , потому что функция reduce требует, чтобы ввод был того же типа, что и вывод.

Ответ №2:

Попробуйте:

 import numpy as np

top_words = {}
for ind, row in df.iterrows():
    for word in row["words"]:
        top_words[word[0]] = (sum(j[1] for i in df["words"]  for j in i if j[0] == word[0]), 
                              sum(i["votes"] for ind, i in df.iterrows() if word[0] in np.array(i["words"])))
  

Комментарии:

1. Это выглядит правильно, но вызывает ошибку поэлементного сравнения. не совсем уверен, почему.