数据帧到按键分组的元组列表的字典

时间:2017-01-18 17:10:32

标签: python pandas dictionary dataframe

我有一个数据帧df,其外观如下:

        a    b    c    d
0       8    xx   17   1.0  
1       8    xy   19   1.0 
2       8    zz   13   0.0
3       9    tt   8    5.0

我正在尝试创建一个包含带有元组列表的键的字典 如下:

{8:[(17,1.0),(19,1.0),(13,0.0)], 9:[(8,5.0)]} 

这里,密钥来自列a,元组列表是列c和列d,其中密钥为a。我也在其他数据集上应用它并尝试了

df_new = df.groupby(['a'])[['c','d']).apply(lambda x: [tuple(x) for x in x.values])

但是,我一直收到错误

raise TypeError('Series.name must be a hashable type')
TypeError: Series.name must be a hashable type

我尝试删除群组中的[' a']并将其保留为' a'如下:

df_new = df.groupby('a')[['c','d']).apply(lambda x: [tuple(x) for x in x.values])

但是,我得到了同样的错误:

raise TypeError('Series.name must be a hashable type')
TypeError: Series.name must be a hashable type

我不想在原始数据帧df中使所有内容都不可变。我希望保持原样。

有没有办法使用pandas功能实现这一目标?我真的不想制作列表,然后通过索引将它们压缩在一起并创建一个字典。

4 个答案:

答案 0 :(得分:3)

使用defaultdict

from collections import defaultdict

d = defaultdict(list)
for tup in df.itertuples():
    d[tup.a].append((tup.c, tup.d))

dict(d)

{8: [(17, 1.0), (19, 1.0), (13, 0.0)], 9: [(8, 5.0)]}

*使用to_dictgroupby *

df.set_index(['c', 'd']).groupby('a').apply(lambda df: df.index.tolist()).to_dict()

{8: [(17, 1.0), (19, 1.0), (13, 0.0)], 9: [(8, 5.0)]}

答案 1 :(得分:3)

只是另一个轻微的变化

df.set_index('a')[['c', 'd']]\
  .apply(tuple, 1)\
  .groupby(level=0)\
  .apply(list)\
  .to_dict()

{8: [(17, 1), (19, 1), (13, 0)], 9: [(8, 5)]}

答案 2 :(得分:2)

我认为这是错误,但与apply合作zip

df = pd.DataFrame({'d': [1.0, 1.0, 0.0, 5.0], 
                   'b': ['xx', 'xy', 'zz', 'tt'], 
                   'a': [8, 8, 8, 9], 
                   'c': [17, 19, 13, 8]})
print (df)
   a   b   c    d
0  8  xx  17  1.0
1  8  xy  19  1.0
2  8  zz  13  0.0
3  9  tt   8  5.0

df_new = df.groupby(['a']).apply(lambda x: list(zip(x.c, x.d))).to_dict()
print (df_new)
{8: [(17, 1.0), (19, 1.0), (13, 0.0)], 9: [(8, 5.0)]}

对我来说,你的版本适用于(有小错字,)已更改为]):

df_new = df.groupby('a')[['c','d']].apply(lambda x: [tuple(x) for x in x.values]).to_dict()
print (df_new)
{8: [(17.0, 1.0), (19.0, 1.0), (13.0, 0.0)], 9: [(8.0, 5.0)]}

答案 3 :(得分:2)

您可以使用词典理解:

{k: list(map(tuple, g[['c','d']].values)) for k, g in df.groupby('a')}
# {8: [(17, 1), (19, 1), (13, 0)], 9: [(8, 5)]}

或另一种方式:

dict((k, list(map(tuple, g[['c','d']].values))) for k, g in df.groupby('a'))