如何将pandas dataframe转换为defaultdict(class,list),其中一个列值用作键?

时间:2017-03-13 19:17:21

标签: python pandas dataframe list-comprehension defaultdict

在给定的pandas数据帧中:

df = 

     contig       pos  PI_index  hapX_My_Sum  hapY_My_Sum  hapX_Sp_Sum       
 0  2  16229767           726          0.0         12.0          3.5   
 1  2  16229783           726          0.0         12.0          3.5   
 3  2  16229880           726          0.0         12.0          2.0   
 4  2  16230491           255         12.0          0.0          0.0   
 5  2  16230503           255         12.0          0.0          0.0   
 6  2  16232072           255         11.0          1.0          0.0   
 7  2  16232072           255         11.0          1.0          0.0   
 8  2  16232282          3353         11.0          1.0          0.0   
 9  2  16232444          3353         11.0          1.0          0.0   
 10 2  16232444          3353         11.0          1.0          0.0   

我想将此数据框转换为dictionary of dictionary,即default(dict)

所以,我做了:

from collections import defaultdict
df_dict = df.to_dict('index')

print(df_dict)  # gives me
{0: {'hapY_My_Sum': 12.0, 'hapX_Sp_Sum': 3.5 .....}

全部,很好但不是使用main pandas index我想使用PI_index作为索引来生成defaultdict(<class 'dict'>,其中PI_index值是keys进行下游分析。

defaultdict的打印输出应为:

defaultdict(<class 'dict'>, {'726': {'contig': '2', 'hapX_My_Sum': ['0.0', '0.0', '0.0'], 'hapY_My_Sum': ['12.0', '12.0', '12.0'], ....}, '255':{'contig': '2', 'hapX_My_Sum': [....]....}})

发布编辑:

  • 我忘了添加,但如果不希望有某种方法可以取消选择某些列,但我不想将它们从pandas数据框中删除。
  • 此外,如果我只想在重叠群中使用一个值,那该怎么办呢?

所以,下游我可以这样做:

for k in df_dict:
    contig = df_dict[k]['chr']

    hapX_My_product = reduce(mul, (float(x) for x in (df_dict[k]['hapX_My_Sum'])))

2 个答案:

答案 0 :(得分:2)

这就是你想要的吗?

In [11]: cols = ['contig','PI_index','hapX_My_Sum']

In [12]: df[cols].groupby('PI_index') \
                 .apply(lambda x: x.set_index('PI_index').to_dict('list')) \
                 .to_dict()
Out[12]:
{255: {'contig': [2, 2, 2, 2], 'hapX_My_Sum': [12.0, 12.0, 11.0, 11.0]},
 726: {'contig': [2, 2, 2], 'hapX_My_Sum': [0.0, 0.0, 0.0]},
 3353: {'contig': [2, 2, 2], 'hapX_My_Sum': [11.0, 11.0, 11.0]}}

一些解释:

首先我们为每个组生成字典

In [87]: df[cols].groupby('PI_index') \
    ...:         .apply(lambda x: x.set_index('PI_index').to_dict('list'))
Out[87]:
PI_index
255     {'contig': [2, 2, 2, 2], 'hapX_My_Sum': [12.0,...
726     {'contig': [2, 2, 2], 'hapX_My_Sum': [0.0, 0.0...
3353    {'contig': [2, 2, 2], 'hapX_My_Sum': [11.0, 11...
dtype: object

现在我们可以将行导出为字典,设置相应的索引并使用默认的orient='dict'

In [88]: df[cols].groupby('PI_index') \
    ...:         .apply(lambda x: x.set_index('PI_index').to_dict('list')) \
    ...:         .to_dict()
Out[88]:
{255: {'contig': [2, 2, 2, 2], 'hapX_My_Sum': [12.0, 12.0, 11.0, 11.0]},
 726: {'contig': [2, 2, 2], 'hapX_My_Sum': [0.0, 0.0, 0.0]},
 3353: {'contig': [2, 2, 2], 'hapX_My_Sum': [11.0, 11.0, 11.0]}}

答案 1 :(得分:0)

这是考虑它的另一种方式。  1.将您的记录转换为词典数组

df_arrDict = df.to_dict('record')
> [{'PI_index': 726.0,
    'contig': 2.0,
    'hapX_My_Sum': 0.0,
    'hapX_Sp_Sum': 3.5,
    'hapY_My_Sum': 12.0,
    'pos': 16229767.0},
    {....
    ]

2。默认词典适合分组数据

  from collections import  defaultdict
  by_PI = defaultdict(list)
  for df_dict in df_arrDict:
      feature = df_dict['PI_index']
      by_PI[feature].append(df_dict)
  1. 最后转换回字典,你可以使用任何方法或字典理解如下

    by_PI_dict = { int(key):val for key,val in by_PI.items()}
    by_PI_dict[255]
    [{'PI_index': 255.0,
        'contig': 2.0,
        'hapX_My_Sum': 12.0,
        'hapX_Sp_Sum': 0.0,
        'hapY_My_Sum': 0.0,
        'pos': 16230491.0},
     {'PI_index': 255.0,
        'contig': 2.0,
        'hapX_My_Sum': 12.0,
        'hapX_Sp_Sum': 0.0,
        'hapY_My_Sum': 0.0,
        'pos': 16230503.0},
     {'PI_index': 255.0,
       'contig': 2.0,
       'hapX_My_Sum': 11.0,
       'hapX_Sp_Sum': 0.0,
       'hapY_My_Sum': 1.0,
       'pos': 16232072.0},
     {'PI_index': 255.0,
       'contig': 2.0,
       'hapX_My_Sum': 11.0,
       'hapX_Sp_Sum': 0.0,
       'hapY_My_Sum': 1.0,
       'pos': 16232072.0}]