我希望能够转换一个n维的numpy数组,例如下面这个:
[ [ a, b, c],
[ d, e, f] ]
将其转化为一个二维数组,包含axis_0_index
、axis_1_index
和cell_value
。
[ [ 0, 0, a],
[ 0, 1, b],
[ 0, 2, c],
[ 1, 0, d],
[ 1, 1, e],
[ 1, 2, f] ]
在NumPy中是否容易做到这一点?
np.where
来获取数组的所有索引,使用与条件相同形状的全为1的数组,然后将这些索引与(扁平化的)数组堆叠,最后进行转置。>>> A = np.array([ [ 'a', 'b', 'c'], [ 'd', 'e', 'f'] ])
>>> ones = np.ones(A.shape)
>>> np.vstack(np.where(ones) + (A.ravel(),)).transpose()
array([['0', '0', 'a'],
['0', '1', 'b'],
['0', '2', 'c'],
['1', '0', 'd'],
['1', '1', 'e'],
['1', '2', 'f']],
dtype='|S1')
经过进一步搜索,可能更干净的方法是使用np.indices
:
>>> X, Y = np.indices(A.shape)
>>> np.vstack((X.ravel(), Y.ravel(), A.ravel())).T
或者
>>> np.vstack((X, Y, A)).reshape(3,A.size).T
结果,在两种情况下都与上面相同。
我使用IPython的%timeit
进行了一些时间分析。奇怪的是,我的第一个带有where
的解决方案似乎是最快的,至少对于这个非常小的测试数组:
>>> %timeit f1() # using ones and np.where
10000 loops, best of 3: 72.3 us per loop
>>> %timeit f2() # using np.indices and ravel
10000 loops, best of 3: 125 us per loop
>>> %timeit f3() # using np.indices and reshape
10000 loops, best of 3: 110 us per loop
>>> %timeit g() # using meshgrid
10000 loops, best of 3: 134 us per loop
np.meshgrid
-In [19]: A
Out[19]:
array([[19, 80, 63],
[24, 54, 44]])
In [20]: m,n = A.shape
In [21]: R,C = np.meshgrid(np.arange(m),np.arange(n))
In [22]: np.column_stack((R.ravel('F'),C.ravel('F'),A.ravel()))
Out[22]:
array([[ 0, 0, 19],
[ 0, 1, 80],
[ 0, 2, 63],
[ 1, 0, 24],
[ 1, 1, 54],
[ 1, 2, 44]])