代码之家  ›  专栏  ›  技术社区  ›  LoneWanderer

使用额外索引键展平数据帧嵌套列表/数组(用于时间序列)

  •  2
  • LoneWanderer  · 技术社区  · 7 年前

    我有一个如下结构的数据框架。(这是JSON规范化的结果)

    mydf
    
    id    colA    colB    ...    colArray
    foo   a1      b1             [{'date': '...', 'data1': '...', 'data2': 0.1 ...}, ...]
    bar   a2      b2             [{'date': '...', 'data1': '...', 'data2': 0.1 ...}, ...]
    fooz  a3      b3             [{'date': '...', 'data1': '...', 'data2': 0.1 ...}, ...]
    barz  a4      b4             [{'date': '...', 'data1': '...', 'data2': 0.1 ...}, ...]
    
    • date
    • colArray 具有不同的长度,但具有完全相同的数组元素结构
    • ['id', 'colA', 'colB']

    我想转换这些数据,以便将它们用作时间序列。 我想要的输出是这样的:

    id    colA    colB    ...    date               data1    data2 ... data n
    foo   a1      b1             '1st timestamp'   'flex'   0.1
    foo   a1      b1             '...'   
    ...
    foo   a1      b1             'last_timestamp'   
    bar   a2      b2             '1st timestamp'   'zorg'
    bar   a2      b2             '...'   
    ...   
    bar   a2      b2             'last_timestamp'   
    fooz  a3      b3             '...'   
    fooz  a3      b3             '...'   
    ...
    fooz  a3      b3             '...'   
    etc.
    

    这将允许我基于元组绘制/分析时间序列,例如 [foo, a1, b1]

    对我来说,这看起来很像 Flatten nested pandas dataframe


    有人对如何实现这一目标有什么建议吗?


    使用以下内容,这与我想要的内容非常接近:

    tmpdf = pd.DataFrame(mydf['colArray'].tolist())
    json_normalize(tmpdf[0])
    

    1. 我把钥匙丢了 ['id'、'colA'、'colB']
    2. 我需要对tmpdf的每一行执行该操作

    第二种方法

    基于 Accessing nested JSON data as dataframes in Pandas

    pd.concat(pd.DataFrame.from_dict(tmp_array) for array in mydf['colArray'])
    

    ). 我觉得这是正确的方法,但我不知道如何保持索引列(这样我就可以通过索引列过滤每个生成的时间序列)。

    可惜没有“json_melt”函数

    第三种方法

    基于这个问题, 展平嵌套数据帧 . 我可以保留索引列,但数组元素仍然是JSON格式的,索引为[0,1,2,…]。我将很难处理可变长度(对于较高的列索引值,有很多NA)


    Create a Pandas DataFrame from deeply nested JSON 但是解决方案基于原始的JSON处理,而我希望在现有的数据帧上这样做

    在Pandas中将嵌套JSON数据作为数据帧访问 这很接近我想要的。

    结果看起来像是我的第一次尝试,但底层JSON数据并没有真正“矩阵化”到数据帧中。

    A rather complex and not satisfaying approach

    编辑: This question is the same

    1 回复  |  直到 7 年前
        1
  •  3
  •   jezrael    7 年前

    使用字典理解 pop 用于提取原始列和 concat 对于 MulltiIndex

    df = pd.concat({k: pd.DataFrame(array) for k, array in mydf.pop('colArray').items()})
    

    keys :

    df = pd.concat([pd.DataFrame(array) for array in mydf.pop('colArray')], keys=mydf.index)
    

    join DataFrame :

    df = df.reset_index(level=1, drop=True).join(mydf).reset_index(drop=True)
    

    样品

    mydf = pd.DataFrame({'id': ['foo', 'bar', 'fooz', 'barz'], 'colA': ['a1', 'a2', 'a3', 'a4'], 'colB': ['b1', 'b2', 'b3', 'b4'], 'colArray': [[{'date': 's', 'data1': 't', 'data2': 0.1}, {'date': 'd', 'data1': 'r', 'data2': 0.8}], [{'date': 'd', 'data1': 'y', 'data2': 0.1}], [{'date': 'g', 'data1': 'u', 'data2': 0.1}], [{'date': 'h', 'data1': 'i', 'data2': 0.1}]]})
    print (mydf)
         id colA colB                                           colArray
    0   foo   a1   b1  [{'date': 's', 'data1': 't', 'data2': 0.1}, {'...
    1   bar   a2   b2        [{'date': 'd', 'data1': 'y', 'data2': 0.1}]
    2  fooz   a3   b3        [{'date': 'g', 'data1': 'u', 'data2': 0.1}]
    3  barz   a4   b4        [{'date': 'h', 'data1': 'i', 'data2': 0.1}]
    

    df = pd.concat({k: pd.DataFrame(array) for k, array in mydf.pop('colArray').items()})
    print (df)
        data1  data2 date
    0 0     t    0.1    s
      1     r    0.8    d
    1 0     y    0.1    d
    2 0     u    0.1    g
    3 0     i    0.1    h
    
    df = df.reset_index(level=1, drop=True).join(mydf).reset_index(drop=True)
    print (df)
      data1  data2 date    id colA colB
    0     t    0.1    s   foo   a1   b1
    1     r    0.8    d   foo   a1   b1
    2     y    0.1    d   bar   a2   b2
    3     u    0.1    g  fooz   a3   b3
    4     i    0.1    h  barz   a4   b4