如何在python中将3d数组转换为数据帧

sty*_*882 7 python dataframe

我有一个 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]]])
Run Code Online (Sandbox Code Playgroud)

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

此处显示了预期结果

添加一个Date列,如指示和列名ABC

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

ajw*_*ood 6

基于对这个问题的回答,我们可以使用 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']
Run Code Online (Sandbox Code Playgroud)

现在我们可以随意重塑它:

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

这是结果:

          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
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要 `pd.DataFrame({'A': A.flatten()}, index=index)['A']` 而不是简单的 `pd.DataFrame(A.flatten(), index=index)` ? (2认同)

unu*_*tbu 4

您可以将 3D 数组转换为 Pandas Panel,然后将其展平为 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')
Run Code Online (Sandbox Code Playgroud)

产量

        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
Run Code Online (Sandbox Code Playgroud)

或者,您可以将数组重塑为 shape (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)
Run Code Online (Sandbox Code Playgroud)

产生相同的结果。