代码之家  ›  专栏  ›  技术社区  ›  Shuvashish Roy

将字典列表展平为数据帧列

  •  1
  • Shuvashish Roy  · 技术社区  · 2 年前

    我有以下包含字典列表的数据

    data= [
     {'Time': 18057610.0,
      'Flux': [{'V0': -1.4209e-15},
       {'V1': 2.7353e-16},
       {'V2': 1.1935e-15},
       {'V3': 1.1624},
       {'V4': -6.1692e-15},
       {'V5': 3.2218e-15}]},
     {'Time': 18057620.4,
      'Flux': [{'V0': 2.4377e-16},
       {'V1': -6.2809e-15},
       {'V2': 1.6456e-15},
       {'V3': 1.1651},
       {'V4': 1.7147e-15},
       {'V5': 9.8872e-16}]},
     {'Time': 18057631.1,
      'Flux': [{'V0': 4.1124e-15},
       {'V1': 1.5598e-15},
       {'V2': -2.325e-16},
       {'V3': 1.1638},
       {'V4': -3.9983e-15},
       {'V5': 4.459e-16}]}]
    

    我想得到这样的东西:

    preferred_df :

                         V0            V1  ...            V4            V5
    Time                                    ...                            
    18057610.0 -1.420900e-15  2.735300e-16  ... -6.169200e-15  3.221800e-15
    18057620.4  2.437700e-16 -6.280900e-15  ...  1.714700e-15  9.887200e-16
    18057631.1  4.112400e-15  1.559800e-15  ... -3.998300e-15  4.459000e-16
    

    我想出了以下代码来实现这个目的:

    df = pd.DataFrame(data).explode('Flux').reset_index(drop=True)
    df = df.join(pd.DataFrame(df.pop('Flux').values.tolist())).groupby('Time').sum()
    

    然而,我不想使用 groupby sum() .还有哪些方法(词典理解?)压平 "Flux" 列,而不获取NaN值,同时展平字典并获取 首选_df ? 我试过了 json_normalize() 但得到了同样的NaN,需要使用 groupby() sum() .

    2 回复  |  直到 2 年前
        1
  •  3
  •   Andrej Kesely    2 年前

    尝试:

    df = pd.DataFrame(
        [{k: v for d2 in d["Flux"] for k, v in d2.items()} for d in data],
        index=[d["Time"] for d in data],
    )
    print(df)
    

    印刷品:

                          V0            V1            V2      V3            V4            V5
    18057610.0 -1.420900e-15  2.735300e-16  1.193500e-15  1.1624 -6.169200e-15  3.221800e-15
    18057620.4  2.437700e-16 -6.280900e-15  1.645600e-15  1.1651  1.714700e-15  9.887200e-16
    18057631.1  4.112400e-15  1.559800e-15 -2.325000e-16  1.1638 -3.998300e-15  4.459000e-16
    
        2
  •  3
  •   enke    2 年前

    你可以使用内置的 collections.ChainMap 列表中的方法:

    from collections import ChainMap
    out = pd.DataFrame([d | ChainMap(*d.pop('Flux')) for d in data])
    

    输出:

             Time            V0            V1            V2      V3            V4            V5
    0  18057610.0 -1.420900e-15  2.735300e-16  1.193500e-15  1.1624 -6.169200e-15  3.221800e-15
    1  18057620.4  2.437700e-16 -6.280900e-15  1.645600e-15  1.1651  1.714700e-15  9.887200e-16
    2  18057631.1  4.112400e-15  1.559800e-15 -2.325000e-16  1.1638 -3.998300e-15  4.459000e-16
    
        3
  •  0
  •   sammywemmy    2 年前

    一个选择是 pd.json_normalize 然后是一个groupby(它不会像前面在Python中进行争论的选项那样高效):

    ( pd
    .json_normalize(data, 'Flux', ['Time'])
    .groupby('Time', as_index = False)
    .min()
    )
    
             Time            V0            V1            V2      V3            V4            V5
    0  18057610.0 -1.420900e-15  2.735300e-16  1.193500e-15  1.1624 -6.169200e-15  3.221800e-15
    1  18057620.4  2.437700e-16 -6.280900e-15  1.645600e-15  1.1651  1.714700e-15  9.887200e-16
    2  18057631.1  4.112400e-15  1.559800e-15 -2.325000e-16  1.1638 -3.998300e-15  4.459000e-1