Igo*_*ush 6 python multidimensional-array multi-index pandas
有没有一种方法可以将带有n级索引的DataFrame 转换为n- D Numpy数组(又名n -tensor)?
假设我设置了一个像DataFrame
from pandas import DataFrame, MultiIndex
index = range(2), range(3)
value = range(2 * 3)
frame = DataFrame(value, columns=['value'],
index=MultiIndex.from_product(index)).drop((1, 0))
print frame
Run Code Online (Sandbox Code Playgroud)
哪个输出
value
0 0 0
1 1
2 3
1 1 5
2 6
Run Code Online (Sandbox Code Playgroud)
该索引是一个2级分层索引.我可以使用数据从数据中提取二维Numpy数组
print frame.unstack().values
Run Code Online (Sandbox Code Playgroud)
哪个输出
[[ 0. 1. 2.]
[ nan 4. 5.]]
Run Code Online (Sandbox Code Playgroud)
这如何推广到n级索引?
玩unstack(),似乎它只能用于按摩DataFrame的二维形状,但不能用于添加轴.
我不能使用eg frame.values.reshape(x, y, z),因为这将要求帧包含确切的x * y * z行,这是无法保证的.这是我试图drop()在上面的例子中通过一行来证明的.
任何建议都非常感谢.
编辑.这种方法比我下面给出的方法更优雅(并且快两个数量级).
# create an empty array of NaN of the right dimensions
shape = map(len, frame.index.levels)
arr = np.full(shape, np.nan)
# fill it using Numpy's advanced indexing
arr[frame.index.labels] = frame.values.flat
Run Code Online (Sandbox Code Playgroud)
原来的解决方案.给定类似于上面的设置,但是在3-D中,
from pandas import DataFrame, MultiIndex
from itertools import product
index = range(2), range(2), range(2)
value = range(2 * 2 * 2)
frame = DataFrame(value, columns=['value'],
index=MultiIndex.from_product(index)).drop((1, 0, 1))
print(frame)
Run Code Online (Sandbox Code Playgroud)
我们有
value
0 0 0 0
1 1
1 0 2
1 3
1 0 0 4
1 0 6
1 7
Run Code Online (Sandbox Code Playgroud)
现在,我们继续使用reshape()路线,但进行一些预处理以确保沿每个维度的长度是一致的.
首先,使用所有维度的完整笛卡尔积重新索引数据框.NaN将根据需要插入值.此操作可能既慢又占用大量内存,具体取决于维度的数量和数据框的大小.
levels = map(tuple, frame.index.levels)
index = list(product(*levels))
frame = frame.reindex(index)
print(frame)
Run Code Online (Sandbox Code Playgroud)
哪个输出
value
0 0 0 0
1 1
1 0 2
1 3
1 0 0 4
1 NaN
1 0 6
1 7
Run Code Online (Sandbox Code Playgroud)
现在,reshape()将按预期工作.
shape = map(len, frame.index.levels)
print(frame.values.reshape(shape))
Run Code Online (Sandbox Code Playgroud)
哪个输出
[[[ 0. 1.]
[ 2. 3.]]
[[ 4. nan]
[ 6. 7.]]]
Run Code Online (Sandbox Code Playgroud)
(相当难看的)单线是
frame.reindex(list(product(*map(tuple, frame.index.levels)))).values\
.reshape(map(len, frame.index.levels))
Run Code Online (Sandbox Code Playgroud)