给定一个数组:
arr = np.array([[1, 3, 7], [4, 9, 8]]); arr array([[1, 3, 7], [4, 9, 8]])
并给出其索引:
np.indices(arr.shape) array([[[0, 0, 0], [1, 1, 1]], [[0, 1, 2], [0, 1, 2]]])
如何将它们整齐地堆叠在一起以形成新的2D阵列?这就是我想要的:
array([[0, 0, 1], [0, 1, 3], [0, 2, 7], [1, 0, 4], [1, 1, 9], [1, 2, 8]])
这是我目前的解决方案:
def foo(arr): return np.hstack((np.indices(arr.shape).reshape(2, arr.size).T, arr.reshape(-1, 1)))
它可以工作,但是执行此操作是否更短/更优雅?
在随后的步骤中使用array-initialization然后broadcasted-assignment分配索引和数组值-
array-initialization
broadcasted-assignment
def indices_merged_arr(arr): m,n = arr.shape I,J = np.ogrid[:m,:n] out = np.empty((m,n,3), dtype=arr.dtype) out[...,0] = I out[...,1] = J out[...,2] = arr out.shape = (-1,3) return out
请注意,我们避免使用np.indices(arr.shape),这可能会减慢速度。
np.indices(arr.shape)
样品运行-
In [10]: arr = np.array([[1, 3, 7], [4, 9, 8]]) In [11]: indices_merged_arr(arr) Out[11]: array([[0, 0, 1], [0, 1, 3], [0, 2, 7], [1, 0, 4], [1, 1, 9], [1, 2, 8]])
性能
arr = np.random.randn(100000, 2) %timeit df = pd.DataFrame(np.hstack((np.indices(arr.shape).reshape(2, arr.size).T,\ arr.reshape(-1, 1))), columns=['x', 'y', 'value']) 100 loops, best of 3: 4.97 ms per loop %timeit pd.DataFrame(indices_merged_arr_divakar(arr), columns=['x', 'y', 'value']) 100 loops, best of 3: 3.82 ms per loop %timeit pd.DataFrame(indices_merged_arr_eric(arr), columns=['x', 'y', 'value'], dtype=np.float32) 100 loops, best of 3: 5.59 ms per loop
注意: 时间包括转换到pandas数据帧,这是该解决方案的最终用例。
pandas