【问题标题】:3 dimensional numpy array to multiindex pandas dataframe3维numpy数组到多索引熊猫数据框
【发布时间】:2017-09-11 15:17:52
【问题描述】:

我有一个 3 维 numpy 数组 (z, x, y)z 是时间维度,xy 是坐标。

我想将其转换为多索引pandas.DataFrame。我希望行索引是 z 维度 并且每一列都具有来自唯一 x、y 坐标的值(因此,每一列都将被多索引)。

最简单的情况(不是多索引):

>>> array.shape
(500L, 120L, 100L)

>>> df = pd.DataFrame(array[:,0,0])

>>> df.shape
(500, 1)

我一直在尝试使用 pd.MultiIndex.from_arrays 将整个数组传递到多索引数据帧中,但出现错误: NotImplementedError: > 1 ndim Categorical 目前不支持

看起来应该很简单,但我想不通。

【问题讨论】:

    标签: python-2.7 pandas numpy multi-index


    【解决方案1】:

    我发现Series with a Multiindex 是最类似的 pandas 数据类型,用于具有任意多维(可能是 3 或更多)的 numpy 数组。

    下面是一些示例代码:

    import pandas as pd
    import numpy as np
    
    time_vals = np.linspace(1, 50, 50)
    x_vals = np.linspace(-5, 6, 12)
    y_vals = np.linspace(-4, 5, 10)
    
    measurements = np.random.rand(50,12,10)
    
    #setup multiindex
    mi = pd.MultiIndex.from_product([time_vals, x_vals, y_vals], names=['time', 'x', 'y'])
    
    #connect multiindex to data and save as multiindexed Series
    sr_multi = pd.Series(index=mi, data=measurements.flatten())
    
    #pull out a dataframe of x, y at time=22
    sr_multi.xs(22, level='time').unstack(level=0)
    
    #pull out a dataframe of y, time at x=3
    sr_multi.xs(3, level='x').unstack(level=1)
    

    【讨论】:

    • 很好地回答了关于将 3D numpy 数组转换为 pandas 的常见问题。比我见过的其他人更容易理解。太棒了@Selah!
    【解决方案2】:

    我认为你可以使用panel - 然后为Multiindex DataFrame 添加to_frame

    np.random.seed(10)
    arr = np.random.randint(10, size=(5,3,2))
    print (arr)
    [[[9 4]
      [0 1]
      [9 0]]
    
     [[1 8]
      [9 0]
      [8 6]]
    
     [[4 3]
      [0 4]
      [6 8]]
    
     [[1 8]
      [4 1]
      [3 6]]
    
     [[5 3]
      [9 6]
      [9 1]]]
    
    df = pd.Panel(arr).to_frame()
    print (df)
                 0  1  2  3  4
    major minor               
    0     0      9  1  4  1  5
          1      4  8  3  8  3
    1     0      0  9  0  4  9
          1      1  0  4  1  6
    2     0      9  8  6  3  9
          1      0  6  8  6  1
    

    transpose 也很有用:

    df = pd.Panel(arr).transpose(1,2,0).to_frame()
    print (df)
                 0  1  2
    major minor         
    0     0      9  0  9
          1      1  9  8
          2      4  0  6
          3      1  4  3
          4      5  9  9
    1     0      4  1  0
          1      8  0  6
          2      3  4  8
          3      8  1  6
          4      3  6  1
    

    concat 的另一种可能解决方案:

    arr = arr.transpose(1,2,0)
    df = pd.concat([pd.DataFrame(x) for x in arr], keys=np.arange(arr.shape[2]))
    print (df)
        0  1  2  3  4
    0 0  9  1  4  1  5
      1  4  8  3  8  3
    1 0  0  9  0  4  9
      1  1  0  4  1  6
    2 0  9  8  6  3  9
      1  0  6  8  6  1
    

    np.random.seed(10)
    arr = np.random.randint(10, size=(500,120,100))
    df = pd.Panel(arr).transpose(2,0,1).to_frame()
    print (df.shape)
    (60000, 100)
    
    print (df.index.max())
    (499, 119)
    

    【讨论】:

    • 谢谢!这越来越接近了。但是数据的形状不正确,我正在寻找 500 行(作为“主要”)和 0 和 1,就像您在最初的示例中一样。但我得到了 500 列。我尝试了不同的转置排列,但仍然不太正确。
    • 您需要500 主要行、120100 次要行和100120 列吗?
    • 如果120 列,可能需要.transpose(1,0,2)
    • 是的,我正在寻找 500 行主要,120 次次要和 100 列。 .transpose(1,0,2) 不起作用。
    • 所以需要.transpose(2,0,1)
    猜你喜欢
    • 2019-12-20
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 2022-07-10
    • 2017-02-22
    • 2019-05-21
    相关资源
    最近更新 更多