【问题标题】:Constructing 3D Pandas DataFrame构建 3D Pandas DataFrame
【发布时间】:2014-08-09 00:58:52
【问题描述】:

我在 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

其中AB 等是顶级描述符,startend 是子描述符。后面的数字是成对的,AB 等的对数不一样。注意A 有四个这样的对,B 只有 1 个,C 有 3 个.

我不确定如何继续构建此 DataFrame。修改 this 示例并没有给我设计的输出:

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

成功:

                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]

有什么方法可以将 C 中的列表分解成各自的列?

编辑:我的C 的结构很重要。如下所示:

 C = [[7,11,56,45], [20,21,74,12], [42], [52], [90,213,9], [101, 34, 45]]

所需的输出是顶部的输出。它表示某个序列内子序列的起点和终点(ABC 是不同的序列)。根据序列本身,有不同数量的子序列满足我正在寻找的给定条件。因此,AB 等的 start:end 对的数量不同

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    正如@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
    

    然后您可以像这样创建一个三维 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"])
    

    我们将三个 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'
    

    【讨论】:

      【解决方案2】:

      首先,我认为你需要填写 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]]
      

      然后,转换为 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
      

      【讨论】:

      • 我的数据被组织为一个列表列表,因此C=[[...],[...],[...]...] 因为每个嵌套列表都有不同的长度。我该如何处理这种情况?
      • 这个实现给了我一个错误,因为C 中嵌套列表的长度不等于AB 的长度
      • 每个列表代表什么,行还是列?为什么它们的长度不同?较短的列表是否应该缺少某些元素?请参阅编辑后的答案以进行猜测。
      • 每个嵌套列表中的值是行,嵌​​套列表本身是列。列的长度不同,因为 one 的 start:end 对数量与 two 不同
      • 我认为我们在术语上有些纠结 - 您能否编辑您的问题以提供一些与您正在谈论的内容相匹配的数据,然后显示您想要的输出?
      【解决方案3】:

      你不能只使用一个面板吗?

      import numpy as np
      import pandas as pd
      
      A = ['one', 'two' ,'three']
      B = ['start','end']
      C = [np.random.randint(10, 99, 2)]*6
      df = pd.DataFrame(C,columns=B  )
      p={}
      for a in A:
          p[a]=df
      panel= pd.Panel(p)
      print panel['one']
      

      【讨论】:

      猜你喜欢
      • 2023-02-09
      • 2014-02-08
      • 2023-04-08
      • 2016-07-14
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      相关资源
      最近更新 更多