Как собрать словари в столбце DataFrame в единый словарь с суммированными значениями?
Есть DataFrame, в котором один из столбцов имеет строковые значения.
В строке стоит словарь по типу 1:259, 2:400, 3:800, 4:1200, 5:800.
В словаре зашифрованы оценки пользователей - 259 человек поставили 1, 400 - 2 и так далее.
Как можно просуммировать значения всех словарей, чтобы получить на выходе один словарь с ключами и суммой значений всех словарей?
Сначала разобрался с проблемой строкового типа данных:
dict_sample = ast.literal_eval(string_sample)
Этo возвращает словарь.
Потом, по логике, я создал пустой словарь - {1:0,2:0,3:0,4:0,5:0}, и циклом прибавил ко всем значениям значения из тестового словаря (dict_sample).
Но тут получился затык, не понимаю, сделать эту же историю для всего столбца.
Пока пробовал написать функцию и применить ее через лямбду к каждому элементу, но что-то не выходит, падает с ошибкой keyerror.
Ответы (1 шт):
Пример:
Исходный DataFrame:
df = pd.DataFrame({
"val": ["{1:100, 2:200, 3:300, 4:400, 5:500}",
"{1:111, 2:222, 3:333, 4:444, 5:555}"]
})
In [21]: df
Out[21]:
val
0 {1:100, 2:200, 3:300, 4:400, 5:500}
1 {1:111, 2:222, 3:333, 4:444, 5:555}
In [22]: type(df.loc[0, "val"])
Out[22]: str
решение:
from ast import literal_eval
res = pd.DataFrame(df["val"].map(literal_eval).to_list()).sum().to_dict()
результат:
In [24]: res
Out[24]: {1: 211, 2: 422, 3: 633, 4: 844, 5: 1055}
решение пошагово:
парсим строки в словари:
In [26]: df["val"].map(literal_eval)
Out[26]:
0 {1: 100, 2: 200, 3: 300, 4: 400, 5: ...
1 {1: 111, 2: 222, 3: 333, 4: 444, 5: ...
Name: val, dtype: object
преобразуем столбец в список элементов:
In [28]: df["val"].map(literal_eval).to_list()
Out[28]:
[{1: 100, 2: 200, 3: 300, 4: 400, 5: 500},
{1: 111, 2: 222, 3: 333, 4: 444, 5: 555}]
создаем развернутый DataFrame из списка, полученного на предыдущем шаге:
In [30]: pd.DataFrame(df["val"].map(literal_eval).to_list())
Out[30]:
1 2 3 4 5
0 100 200 300 400 500
1 111 222 333 444 555
суммируем значения в столбцах фрейма, полученного на предыдущем шаге:
In [31]: pd.DataFrame(df["val"].map(literal_eval).to_list()).sum()
Out[31]:
1 211
2 422
3 633
4 844
5 1055
dtype: int64
преобразуем полученный результат в словарь:
In [32]: pd.DataFrame(df["val"].map(literal_eval).to_list()).sum().to_dict()
Out[32]: {1: 211, 2: 422, 3: 633, 4: 844, 5: 1055}