用另一个numpy数组的值逐行替换numpy数组

3

我有一个三维 numpy 数组,其中存储了 01

g = np.array([[[0, 1], [0, 1], [1, 0]], [[0, 0], [1, 0], [1, 1]]])
# array([
#     [[0, 1], [0, 1], [1, 0]],
#     [[0, 0], [1, 0], [1, 1]]])

我想使用一种逐行替换的策略,将这些值替换为另一个数组中的值。例如,用x替换g的值:

x = np.array([[2, 3], [4, 5]])
array([[2, 3],
       [4, 5]])

获取:

array([
     [[2, 3], [2, 3], [3, 2]],
     [[4, 4], [5, 4], [5, 5]]])

这里的想法是将g的第一行替换为x的第一个元素(0变为21变为3),并对另一行执行相同操作(第一维——“行”数——始终对gx相同)。

我似乎无法使用np.where,因为出现了ValueError: operands could not be broadcast together with shapes (2,3,2) (2,2) (2,2)

4个回答

3

IIUC,

np.stack([x[i, g[i]] for i in range(x.shape[0])])

输出:

array([[[2, 3],
        [2, 3],
        [3, 2]],

       [[4, 4],
        [5, 4],
        [5, 5]]])

3

使用np.take_along_axis的向量化方法,通过使用axis=-1g索引到x的最后一个轴 -

In [20]: np.take_along_axis(x[:,None],g,axis=-1)
Out[20]: 
array([[[2, 3],
        [2, 3],
        [3, 2]],

       [[4, 4],
        [5, 4],
        [5, 5]]])

或者通过手动整数索引 -

In [27]: x[np.arange(len(g))[:,None,None],g]
Out[27]: 
array([[[2, 3],
        [2, 3],
        [3, 2]],

       [[4, 4],
        [5, 4],
        [5, 5]]])

一个向量化的方法很有趣。我很惊讶它花费的时间与基于列表推导的其他答案差不多。 - PedroA
你可以看一下这个比较 - cglacet
1
@PedroA 如果想要实现向量化处理,你需要输入一些比这些示例更大的数据。 - Divakar
1
在这种特定情况下,它确实更快,但并没有显著地更快。例如,对于一个100^3的矩阵,它大约需要4毫秒,而np.stack([x[i, g[i]] ...则需要约6毫秒,而列表推导式则需要约14.5毫秒。 - cglacet

1

一个解决方案是直接在这里使用推导式:

>>> np.array([[x[i][c] for c in r] for i, r in enumerate(g)])
array([[[2, 3],
        [2, 3],
        [3, 2]],

       [[4, 4],
        [5, 4],
        [5, 5]]])

1
据我所知,g是一个索引数组(索引为0或1),x是你使用其值的数组。
类似以下代码应该可以工作(经过快速测试):
import numpy as np

def swap_indexes(index_array, array):
   out_array = []
   for i, row in enumerate(index_array):
         out_array.append([array[i,indexes] for indexes in row])
   return np.array(out_array)


index_array = np.array([[[0, 1], [0, 1], [1, 0]], [[0, 0], [1, 0], [1, 1]]])
x = np.array([[2, 3], [4, 5]])
print(swap_indexes(index_array, x))

抱歉,我需要更具体的文本才能翻译。请提供完整的句子或段落。

"g是索引数组。这是一个有趣的方法。我之前没有这样看过,但在我使用的情况下很有道理。不过,这个函数似乎返回了重复项。有什么办法可以解决吗?" - PedroA
@PedroA 你说得对,我在函数中打错了字,现在不应该再返回重复项了。 - rob_m

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接