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

时间:2016-08-11 16:49:10

标签: python pandas dictionary group-by

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

  

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

     

注意: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