2017-04-15 111 views
1

我有一个3维numpy数组,(z, x, y)z是时间维度,并且xy是坐标。我想将其转换为多索引pandas.DataFrame。我希望行索引是z维 ,并且每列都具有唯一x,y坐标的值(因此,每列都将被多索引)。3维numpy数组到多索引熊猫数据帧

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

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

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

>>> df.shape 
(500, 1) 

我一直在尝试使用pd.MultiIndex.from_arrays通过整个阵列成多指标数据帧,但我得到一个错误: NotImplementedError:> 1 ndim目前不支持分类

看起来应该是相当简单的,但我无法弄清楚。

回答

1

我认为你可以使用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) 
+0

谢谢!这越来越接近。但数据的形状是不正确的,我正在寻找500行(作为“主要”)和0和1作为你的初始例子中的次要。但是我得到500列。我尝试了不同的转置排列,但仍不完全正确。 – BioProg

+0

你是否需要'小'和'100'或'120'列中的'500'行,主要是'120'还是'100'? – jezrael

+0

也许需要'.transpose(1,0,2)'如果是'120'列。 – jezrael

0

我发现一个Series with a Multiindex是一个numpy数组最大的熊猫数据类型,任意多维(推测是3或更多)。

下面是一些示例代码:

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)