#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. Это выглядит правильно, но вызывает ошибку поэлементного сравнения. не совсем уверен, почему.