Извлечение информации из словарей в пандах [закрыто]Python

Программы на Python
Anonymous
Извлечение информации из словарей в пандах [закрыто]

Сообщение Anonymous »

Скажем, у меня есть фрейм данных следующей формы

Код: Выделить всё

import pandas as pd

d1 = str([{"Alice": "1/2"}, {"Bob": "3/11"}, {"Charlotte": "5/2"}])
d2 = str([{"Bob": "2/7"}, {"Daniel": "4/5"}])
d3 = str([{"Emily": "12/5"}])
d4 = str([{"Bob": "4/11"}, {"Victor": "2/2"}, {"Bob": "5/6"}])
df = pd.DataFrame([d1, d2, d3, d4], columns=['visits'])
Я думаю, что каждая строка в df соответствует палате в клинике, и каждый словарь содержит имя пациента, который был в этой палате, и день, когда он там был. Я хочу создать новый столбец для каждого пациента, в котором будет подсчитываться, сколько раз каждый пациент был в каждой палате (т. е. сколько словарей в столбце имеют это имя в качестве ключа), поэтому он должен выглядеть так:

Код: Выделить всё

df_desired = pd.DataFrame(
[[d1, 1, 1, 1, 0, 0, 0],
[d2, 0, 1, 0, 1, 0, 0],
[d3, 0, 0, 0, 0, 1, 0],
[d4, 0, 2, 0, 0, 0, 1]],
columns=['visits', 'Alice', 'Bob', 'Charlotte', 'Daniel', 'Emily', 'Victor'])
Как это реализовать? Важно отметить, что я априори не знаю, кем будут все пациенты (то есть ключи в словаре). Я знаю, что это было бы относительно просто сделать с помощью итерации по строкам, но я знаю, что одно из золотых правил Pandas заключается в том, что итерация по строкам никогда не является правильным ответом, поскольку производительность очень низкая.
РЕДАКТИРОВАТЬ: Я придумал решение, которое, казалось, работало, но был бы признателен за совет о том, как его можно улучшить.
Несколько комментаторов спросили, почему словари хранятся в виде строк. Я сделал это, потому что (1) именно так он хранится в моем наборе данных и (2) иногда Pandas выдает исключения, когда я пытаюсь использовать нехешируемые типы данных, поэтому я хотел предотвратить это.
Мое решение было следующим:

Код: Выделить всё

def get_patient_list():
"""This function returns a list of all the patient names
appearing in the visits column."""
patient_list = []
def fn1(row):
visits_list = eval(row['visits'])
for visit in visits_list:
for name in visit.keys():
if name not in patient_list:
patient_list.append(name)
df.apply(fn1, axis=1)
return patient_list

# Now that I have a list of all the patients, I can make a column for
# each patient, and just count for each row how many times that
# patient visited.

for patient in get_patient_list():
def visits_counter(row):
visits_list = eval(row['visits'])
counter = 0
for visit in visits_list:
if patient in visit.keys():
counter += 1
return counter
df[patient] = df.apply(visits_counter, axis=1)
Этот метод делает то, что я хотел, но это, конечно, игрушечный пример, далеко не достаточно большой, чтобы протестировать мой подход. Есть ли более стандартный способ, которым мне следовало бы это сделать?

Вернуться в «Python»