#python #pandas #dataframe
Вопрос:
Я хочу вычислить процентное распределение по элементам и получить выходной словарь, состоящий из time_key
ключей и словаря с процентом элементов в качестве значения
Я написал этот код
def class_distr(x):
fractions = x.value_counts(normalize=True) # use value_counts normalize instead
return [dict(zip(fractions.keys(), fractions.tolist()))]
def get_dict(df, col):
grouped = df[['time_key', col]].groupby('time_key')[col].apply(lambda x: class_distr(x)).reset_index(name=col)
return {key: value for key, value in zip(grouped['time_key'], grouped[col])}
Вот фрейм данных:
d = {'time_key': {9394: '2019-03-01',
898: '2018-09-01',
2398: '2018-10-01',
5906: '2018-12-01',
2343: '2018-10-01',
8225: '2019-02-01',
5506: '2018-12-01',
6451: '2019-01-01',
2670: '2018-10-01',
3497: '2018-10-01'},
'target': {9394: 3,
898: 4,
2398: 0,
5906: 3,
2343: 4,
8225: 1,
5506: 0,
6451: 0,
2670: 0,
3497: 2}}
df = pd.DataFrame(d)
get_dict(df, 'target')
Выход
{'2018-09-01': [{4: 1.0}],
'2018-10-01': [{0: 0.5, 2: 0.25, 4: 0.25}],
'2018-12-01': [{3: 0.5, 0: 0.5}],
'2019-01-01': [{0: 1.0}],
'2019-02-01': [{1: 1.0}],
'2019-03-01': [{3: 1.0}]}
Видно, что внутренние словари заключены в квадратные скобки.
Мне это не нужно, но class_distr
функция неправильно работает без скобок в сочетании с groupby
.
Как я могу справиться с этим без дополнительного цикла для извлечения словарей из скобок?
Ответ №1:
Мы можем group
к тому target
времени в столбце time_key
внутри dict
понимания выполнить итерацию по группам и создать пары ключ-значение, где ключ-это метка времени, а значение-нормализованное распределение target
для соответствующей метки времени
grp = df.groupby('time_key')['target']
{k: g.value_counts(normalize=True).to_dict() for k, g in grp}
{'2018-09-01': {4: 1.0},
'2018-10-01': {0: 0.5, 4: 0.25, 2: 0.25},
'2018-12-01': {0: 0.5, 3: 0.5},
'2019-01-01': {0: 1.0},
'2019-02-01': {1: 1.0},
'2019-03-01': {3: 1.0}}