将数据框列转换为字典

时间:2015-09-16 14:51:35

标签: python pandas

我有大型Pandas数据框,看起来像这样:

  Label1 Label2 Label3   Id1  Val1   Id2  Val2   Id3  Val3
0      A      B      C     a  0.80     b  0.79     c  0.29
1      A      B      D  None   NaN  None   NaN     e  0.06
2      E      B      F  None   NaN     b  0.86  None   NaN
3      E      G      H     b  0.16  None   NaN     f  0.34

我想将Id1之前的列转换为类似的字典:

  Label1 Label2 Label3                               kvp
0      A      B      C  {'a': 0.8, 'b': 0.79, 'c': 0.29}
1      A      B      D                       {'e': 0.06}
2      E      B      F                       {'b': 0.86}
3      E      G      H            {'b': 0.16, 'f': 0.34}

这种选择和转换是否有Pandas成语,或者我是否必须编写代码来遍历行?

1 个答案:

答案 0 :(得分:1)

您可以通过获取相关列,将它们重新整形为2列numpy数组,然后将其转换为dict来为单行创建字典:

>>> a
  Label1 Label2 Label3   Id1  Val1   Id2  Val2   Id3  Val3
0      A      B      C     a  0.80     b  0.79     c  0.29
1      A      B      D  None   NaN  None   NaN     e  0.06
2      E      B      F  None   NaN     b  0.86  None   NaN
3      E      G      H     b  0.16  None   NaN     f  0.34

>>> a.irow(0)[3:].reshape(3,2)
array([['a', 0.80000000000000004],
       ['b', 0.79000000000000004],
       ['c', 0.28999999999999998]], dtype=object)
>>> dict(_)
{'b': 0.79000000000000004, 'c': 0.28999999999999998, 'a': 0.80000000000000004}

您可以编写一个使用该原则的函数来创建旧行的新行:

def adjust_row(row):
    kvp_data = row[3:].valid()
    kvp_data = kvp_data.reshape(kvp_data.size//2, 2)
    kvp = dict(kvp_data)
    return row[:3].append(pd.Series({'kvp': kvp}))

请注意,这会将NoneNaN排除在valid()之外,计算临时numpy数组的相应行数。验证它对任何给定行都是正确的:

>>> adjust_row(a.irow(1))
Label1              A
Label2              B
Label3              D
kvp       {'e': 0.06}
dtype: object

完成后,您可以使用数据框架上的apply方法将其应用于每一行:

>>> a.apply(adjust_row, axis=1)
  Label1 Label2 Label3                               kvp
0      A      B      C  {'b': 0.79, 'c': 0.29, 'a': 0.8}
1      A      B      D                       {'e': 0.06}
2      E      B      F                       {'b': 0.86}
3      E      G      H            {'f': 0.34, 'b': 0.16}