самый быстрый способ получить частоту значений, сохраненных в формате словаря в groupby pandas - PullRequest
1 голос
/ 18 июня 2020

Чтобы вычислить частоту каждого значения по идентификатору, мы можем что-то сделать, используя value_counts и groupby.

>>> df = pd.DataFrame({"id":[1,1,1,2,2,2], "col":['a','a','b','a','b','b']})
>>> df
   id col
0   1   a
1   1   a
2   1   b
3   2   a
4   2   b
5   2   b
>>> df.groupby('id')['col'].value_counts()
id  col
1   a      2
    b      1
2   b      2
    a      1

Но я хотел бы, чтобы результаты сохранялись в формате словаря, а не серии. Итак, как я могу достичь этого, а также скорость высокая, если у нас есть большой набор данных? Идеальный формат:

id
1    {'a': 2, 'b': 1}
2    {'a': 1, 'b': 2}

Ответы [ 2 ]

3 голосов
/ 18 июня 2020

Вы можете распаковать результат groupby, чтобы получить dict-of-dicts:

df.groupby('id')['col'].value_counts().unstack().to_dict(orient='index')
# {1: {'a': 2, 'b': 1}, 2: {'a': 1, 'b': 2}}

Если вам нужна серия dicts, используйте agg вместо to_dict:

df.groupby('id')['col'].value_counts().unstack().agg(pd.Series.to_dict)

col
a    {1: 2, 2: 1}
b    {1: 1, 2: 2}
dtype: object

Я не рекомендую хранить данные в этом формате, с объектами обычно труднее работать.


Если при распаковке генерируются NaN, попробуйте альтернативу с GroupBy.agg:

df.groupby('id')['col'].agg(lambda x: x.value_counts().to_dict())

id
1    {'a': 2, 'b': 1}
2    {'b': 2, 'a': 1}
Name: col, dtype: object
2 голосов
/ 18 июня 2020

Мы можем pd.crosstab

pd.Series(pd.crosstab(df.id,df.col).to_dict('i'))
1    {'a': 2, 'b': 1}
2    {'a': 1, 'b': 2}
dtype: object
...