使用NumPy从另一个数组及其索引创建2D数组

发布于 2021-01-29 17:58:04

给定一个数组:

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)))

它可以工作,但是执行此操作是否更短/更优雅?

关注者
0
被浏览
70
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    在随后的步骤中使用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),这可能会减慢速度。

    样品运行-

    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数据帧,这是该解决方案的最终用例。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看