【问题标题】:How to transform a 3d arrays into a dataframe in python如何在 python 中将 3d 数组转换为数据框
【发布时间】:2016-06-02 04:34:11
【问题描述】:

我有一个 3d 数组如下:

    ThreeD_Arrays = np.random.randint(0, 1000, (5, 4, 3))
    
    array([[[715, 226, 632],
            [305,  97, 534],
            [ 88, 592, 902],
            [172, 932, 263]],

           [[895, 837, 431],
            [649, 717,  39],
            [363, 121, 274],
            [334, 359, 816]],

           [[520, 692, 230],
            [452, 816, 887],
            [688, 509, 770],
            [290, 856, 584]],

           [[286, 358, 462],
            [831,  26, 332],
            [424, 178, 642],
            [955,  42, 938]], 

           [[ 44, 119, 757],
            [908, 937, 728],
            [809,  28, 442],
            [832, 220, 348]]])

现在我想把它变成这样的DataFrame

添加一个Date 列(如所示)和列名称ABC

如何进行这种转换?谢谢!

【问题讨论】:

    标签: python dataframe


    【解决方案1】:

    您可以将 3D 数组转换为 Pandas 面板,然后将其展平为 2D DataFrame(使用 .to_frame()):

    import numpy as np
    import pandas as pd
    np.random.seed(2016)
    
    arr = np.random.randint(0, 1000, (5, 4, 3))
    pan = pd.Panel(arr)
    df = pan.swapaxes(0, 2).to_frame()
    df.index = df.index.droplevel('minor')
    df.index.name = 'Date'
    df.index = df.index+1
    df.columns = list('ABC')
    

    产量

            A    B    C
    Date               
    1     875  702  266
    1     940  180  971
    1     254  649  353
    1     824  677  745
    ...
    4     675  488  939
    4     382  238  225
    4     923  926  633
    4     664  639  616
    4     770  274  378
    

    或者,您可以将数组重新整形为 (20, 3),像往常一样形成 DataFrame,然后修复索引:

    import numpy as np
    import pandas as pd
    np.random.seed(2016)
    
    arr = np.random.randint(0, 1000, (5, 4, 3))
    df = pd.DataFrame(arr.reshape(-1, 3), columns=list('ABC'))
    df.index = np.repeat(np.arange(arr.shape[0]), arr.shape[1]) + 1
    df.index.name = 'Date'
    print(df)
    

    产生相同的结果。

    【讨论】:

    • 非常感谢!乌努布!有用!但是我想将数据绘制在类似海生的图表中,并且需要比“ABC”更复杂的列名,说它应该是“Abc”、“Def”、“Ghi” 它是如何工作的?我喜欢的类似海生的disgram实现如下: df = pd.melt(df, id_vars=["date"], var_name="condition") ax = df.groupby(["condition", "date" ]).mean().unstack("condition").plot() x = np.arange(1990,1993) palette = sns.color_palette() 来源:stackoverflow.com/questions/22795348/…
    【解决方案2】:
    ThreeD_Arrays = np.random.randint(0, 1000, (5, 4, 3))
    df = pd.DataFrame([list(l) for l in ThreeD_Arrays]).stack().apply(pd.Series).reset_index(1, drop=True)
    df.index.name = 'Date'
    df.columns = list('ABC')
    

    【讨论】:

    • 谢谢@Jarad!我的新问题是如何使您的代码生成的 df 适合以下代码: df = pd.melt(df, id_vars=["date"], var_name="condition") ax = df.groupby(["condition ", "date"]).mean().unstack("condition").plot() 以及如何用列名 "AAA"、"BBB"、"CCC" 替换 list('ABC')?
    【解决方案3】:

    根据this question 的答案,我们可以使用MultiIndex。首先,创建 MultiIndex 和一个扁平化的 DataFrame。

    A = np.random.randint(0, 1000, (5, 4, 3))
    
    names = ['x', 'y', 'z']
    index = pd.MultiIndex.from_product([range(s)for s in A.shape], names=names)
    df = pd.DataFrame({'A': A.flatten()}, index=index)['A']
    

    现在我们可以随心所欲地重塑它:

    df = df.unstack(level='x').swaplevel().sort_index()
    df.columns = ['A', 'B', 'C']
    df.index.names = ['DATE', 'i']
    

    这是结果:

              A    B    C
    DATE i           
    0    0  715  226  632
         1  895  837  431
         2  520  692  230
         3  286  358  462
         4   44  119  757
    1    0  305   97  534
         1  649  717   39
         2  452  816  887
         3  831   26  332
         4  908  937  728
    2    0   88  592  902
         1  363  121  274
         2  688  509  770
         3  424  178  642
         4  809   28  442
    3    0  172  932  263
         1  334  359  816
         2  290  856  584
         3  955   42  938
         4  832  220  348
    

    【讨论】:

    • 这个答案的第一部分是我认为将多维 Numpy 数组转换为 Pandas 数据帧的最佳方式。
    • 熊猫面板已被贬值,所以这应该是现在接受的答案。
    • 为什么需要pd.DataFrame({'A': A.flatten()}, index=index)['A'] 而不是简单的pd.DataFrame(A.flatten(), index=index)
    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 2016-06-12
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多