Python Pandas:如何将列中的分组列表作为字典返回

Posted

技术标签:

【中文标题】Python Pandas:如何将列中的分组列表作为字典返回【英文标题】:Python Pandas : How to return grouped lists in a column as a dict 【发布时间】:2016-12-18 12:40:22 【问题描述】:

Python Pandas : How to compile all lists in a column into one unique list

从上一个问题的数据开始:

f = pd.DataFrame('id':['a','b', 'a'], 'val':[['val1','val2'],
                                               ['val33','val9','val6'],
                                               ['val2','val6','val7']])

print (df)
  id                  val
0  a         [val1, val2]
1  b  [val33, val9, val6]
2  a   [val2, val6, val7]

如何将列表放入 Dict:

pd.Series([a for b in df.val.tolist() for a in b]).value_counts().to_dict()
'val1': 1, 'val2': 2, 'val33': 1, 'val6': 2, 'val7': 1, 'val9': 1

如何按组获取列表:

df.groupby('id')["val"].apply(lambda x: (list([a for b in x.tolist() for a in b])))

id
a    [val1, val2, val2, val6, val7]
b               [val33, val9, val6]
Name: val, dtype: object

如何按组获取列表作为字典

df.groupby('id')["val"].apply(lambda x: pd.Series([a for b in x.tolist() for a in b]).value_counts().to_dict() )

返回:

id       
a   val1     1.0
    val2     2.0
    val6     1.0
    val7     1.0
b   val33    1.0
    val6     1.0
    val9     1.0
Name: val, dtype: float64

期望的输出 我忽略了什么? :

   id
   a     'val1': 1, 'val2': 2, 'val6': 2, 'val7': 1
   b     'val33': 1, 'val6': 1,  'val9': 1
   Name: val, dtype: object

【问题讨论】:

【参考方案1】:

使用来自@ayhan 的agg 编辑(比应用快得多)。

from collections import Counter
df.groupby("id")["val"].agg(lambda x: Counter([a for b in x for a in b]))

输出:

id
a    'val2': 2, 'val6': 1, 'val7': 1, 'val1': 1
b              'val9': 1, 'val33': 1, 'val6': 1
Name: val, dtype: object

这个版本的时间:

%timeit df.groupby("id")["val"].agg(lambda x: Counter([a for b in x for a in b]))

1000 loops, best of 3: 820 µs per loop

@ayhan 版本时间:

%timeit  df.groupby('id')["val"].agg(lambda x: pd.Series([a for b in x.tolist() for a in b]).value_counts().to_dict() )

100 loops, best of 3: 1.91 ms per loo

【讨论】:

【参考方案2】:

应用灵活。只要有可能,它就会将返回的对象转换为更有用的东西。来自docs:

对分组数据的某些操作可能不适合 聚合或转换类别。或者,您可能只是希望 GroupBy 推断如何组合结果。对于这些,使用 apply 函数, 在许多情况下,它可以替代聚合和转换 标准用例。

注意:apply 可以充当 reducer、transformer 或 filter 函数, 具体取决于传递给应用的内容。所以取决于路径 采取,正是你分组。因此分组的列 可以包含在输出中以及设置索引。

在某些情况下,您可能希望避免这种行为。如果要分组,只需将 apply 替换为 agg:

df.groupby('id')["val"].agg(lambda x: pd.Series([a for b in x.tolist() for a in b]).value_counts().to_dict() )
Out: 
id
a    'val1': 1, 'val7': 1, 'val6': 1, 'val2': 2
b              'val6': 1, 'val33': 1, 'val9': 1
Name: val, dtype: object

【讨论】:

请注意,我在这里不是为了速度,我只是在解释为什么 apply 的行为不符合您的预期。 不是有意打扰,但为什么我得到的结果是`bultin-methon-values of dict`,我怎样才能像你一样打印结果? @Tangfeifan 好像有个bug已经修复了github.com/pandas-dev/pandas/issues/16741我觉得0.21版还没有发布。

以上是关于Python Pandas:如何将列中的分组列表作为字典返回的主要内容,如果未能解决你的问题,请参考以下文章

Pandas - 将列值组合到新列中的列表中

Python Pandas:通过重复项将列组合在一起,并在相应列中连接字符串

熊猫:将列中的列表拆分为多行[重复]

按列表列中的元素对 Pandas 数据框进行分组

合并 Pandas 列中的列表,其中列名在列表中

Python pandas:使用方法链接将列添加到分组的 DataFrame