构建3D Pandas DataFrame

tln*_*agy 21 python pandas

我在Pandas中构建3D DataFrame时遇到了困难.我想要这样的东西

A               B               C
start    end    start    end    start    end ...
7        20     42       52     90       101
11       21                     213      34
56       74                     9        45
45       12
Run Code Online (Sandbox Code Playgroud)

where A,B等是顶级描述符,start并且end是subdescriptors.随后的数字是成对的,并且没有相同数量的对A,B等等.观察A有四个这样的对,B只有1,并且C有3个.

我不知道如何继续构建这个DataFrame.修改这个例子没有给我设计输出:

import numpy as np
import pandas as pd

A = np.array(['one', 'one', 'two', 'two', 'three', 'three'])
B = np.array(['start', 'end']*3)
C = [np.random.randint(10, 99, 6)]*6
df = pd.DataFrame(zip(A, B, C), columns=['A', 'B', 'C'])
df.set_index(['A', 'B'], inplace=True)
df
Run Code Online (Sandbox Code Playgroud)

产生:

                C
 A          B   
 one        start   [22, 19, 16, 20, 63, 54]
              end   [22, 19, 16, 20, 63, 54]
 two        start   [22, 19, 16, 20, 63, 54]
              end   [22, 19, 16, 20, 63, 54]
 three      start   [22, 19, 16, 20, 63, 54]
              end   [22, 19, 16, 20, 63, 54]
Run Code Online (Sandbox Code Playgroud)

有没有办法将C中的列表分解为自己的列?

编辑:我的结构C很重要.它看起来如下:

 C = [[7,11,56,45], [20,21,74,12], [42], [52], [90,213,9], [101, 34, 45]]
Run Code Online (Sandbox Code Playgroud)

并且所需的输出是顶部的输出.它表示某个序列中子序列的起点和终点(A,B.C是不同的序列).根据序列本身,有不同数量的子序列满足我正在寻找的给定条件.其结果是,有不同数量的启动:为结束对A,B

chr*_*isb 13

首先,我认为您需要填写C来表示缺失值

In [341]: max_len = max(len(sublist) for sublist in C)
In [344]: for sublist in C:
     ...:     sublist.extend([np.nan] * (max_len - len(sublist)))

In [345]: C
Out[345]: 
[[7, 11, 56, 45],
 [20, 21, 74, 12],
 [42, nan, nan, nan],
 [52, nan, nan, nan],
 [90, 213, 9, nan],
 [101, 34, 45, nan]]
Run Code Online (Sandbox Code Playgroud)

然后,转换为numpy数组,转置,并与列一起传递给DataFrame构造函数.

In [288]: C = np.array(C)
In [289]: df = pd.DataFrame(data=C.T, columns=pd.MultiIndex.from_tuples(zip(A,B)))

In [349]: df
Out[349]: 
     one         two       three     
   start  end  start  end  start  end
0      7   20     42   52     90  101
1     11   21    NaN  NaN    213   34
2     56   74    NaN  NaN      9   45
3     45   12    NaN  NaN    NaN  NaN
Run Code Online (Sandbox Code Playgroud)


sco*_*owe 5

正如@Aaron在上面的评论中提到的,面板已弃用。此外,@ tlnagy提到他的数据集将来可能会扩展到3个以上的维度。

这听起来像是xarray包的一个好用例,它提供了任意多个维度的语义标记数组。Pandas和xarray具有强大的转换支持,为了支持使用xarray,不建议使用面板。

问题的初始设置。

import numpy as np

A = np.array([[7,11,56,45], [20,21,74,12]]).T
B = np.array([[42], [52]]).T
C = np.array([[90,213,9], [101, 34, 45]]).T
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建一个三维xarray.DataArray对象,如下所示:

import xarray

output_as_dataarray = xarray.concat(
    [xarray.DataArray(X, 
                      dims=['record', 'edge'],
                      coords={'record': range(X.shape[0]),
                              'edge': ['start', 'end']},
                     ) for X in (A, B, C)],
    dim='descriptor',
).assign_coords(descriptor=['A', 'B', 'C'])
Run Code Online (Sandbox Code Playgroud)

我们将三个2D numpy数组转换为xarray.DataArray对象,然后将它们沿着新维度连接在一起。

我们的输出如下所示:

<xarray.DataArray (descriptor: 3, record: 4, edge: 2)>
array([[[  7.,  20.],
        [ 11.,  21.],
        [ 56.,  74.],
        [ 45.,  12.]],

       [[ 42.,  52.],
        [ nan,  nan],
        [ nan,  nan],
        [ nan,  nan]],

       [[ 90., 101.],
        [213.,  34.],
        [  9.,  45.],
        [ nan,  nan]]])
Coordinates:
  * record      (record) int64 0 1 2 3
  * edge        (edge) <U5 'start' 'end'
  * descriptor  (descriptor) <U1 'A' 'B' 'C'
Run Code Online (Sandbox Code Playgroud)