numpy:插入数组代替元素
numpy: insert array in place of an element
输入:
import numpy as np
a = np.array([
[0, 1, 0],
[1, 0, 0]
])
期望的输出:
b = np.array([
[[0, 0],[1, 1], [0, 0]],
[[1, 1], [0, 0], [0, 0]]
])
我尝试过的:
b = np.where(a == 0, np.array([0, 0]), np.array([1, 1]))
上面的代码给了我一个ValueError: operands could not be broadcast together with shapes (<a's dimentions>) (2,) (2,)
编辑:我这边的例子不好。我认为让它变得简单会使它更具可读性。但是我不一定要 ones
代替 1 和 zeros
代替 0,并且输入不限于 0s 和 1s。相反,我希望输入类似于:
a = np.array([
[0, 1, 0],
[1, 2, 0]
])
输出为:
b = np.array([
[[5, 6],[8, 2], [5, 6]],
[[8, 2], [7, 4], [5, 6]]
])
你可以使用面具和numpy broadcasting
import numpy as np
a = np.array([[0, 1, 0],
[1, 2, 0]])
d = {0: [5, 6],
1: [8, 2],
2: [7, 4]}
# Initialize b
b = np.zeros((a.shape[0], a.shape[1], 2))
for k,v in d.items():
m = a==k
b += m[...,None] * np.tile(v, (a.shape[0], a.shape[1], 1))
b
array([[[5., 6.],
[8., 2.],
[5., 6.]],
[[8., 2.],
[7., 4.],
[5., 6.]]])
您可以扩展维度然后沿新维度重复(或重复然后重塑):
np.repeat(np.expand_dims(a, axis=2), 2, axis=2)
输出:
[[[0 0]
[1 1]
[0 0]]
[[1 1]
[0 0]
[0 0]]]
如果您想要不同的输出,现在您可以更轻松地将您的条件应用于新数组。
更新:针对一般情况对 post 进行的每次编辑:假设您有一个映射字典(取决于您的映射,解决方案可能会有所不同)
map_dict = {0: [5, 6],
1: [8, 2],
2: [7, 4]}
indexer = np.array([map_dict.get(i, [-1,-1]) for i in range(np.amax(a)+1)])[a]
或者在更具体的情况下,如果您的映射包括 0 和 max(a) 之间的所有整数,就像您的示例一样,请使用:
indexer = np.array([map_dict[i] for i in np.unique(a)])[a]
输出:
[[[5 6]
[8 2]
[5 6]]
[[8 2]
[7 4]
[5 6]]]
假设 a
的元素是数组 c
:
的有效行索引值
In [964]: c = np.array([[5,6], [8,2], [7,4]])
In [965]: a = np.array([[0,1,0],[1,2,0]])
In [966]: c[a,:]
Out[966]:
array([[[5, 6],
[8, 2],
[5, 6]],
[[8, 2],
[7, 4],
[5, 6]]])
这是对您的规范的最简单解释。如果 c
不是像这样的二维数组,或者 a
不只是映射到行,你将不得不做更多的工作来转换它们(并且很可能会丢失大部分 numpy
数组优势).
我要强调这不是 'insert' 或 'in-place' 映射。 a
保持不变。它是一个 (2,3) 数组,Out[966]
是一个 (2,3,2) 数组。
输入:
import numpy as np
a = np.array([
[0, 1, 0],
[1, 0, 0]
])
期望的输出:
b = np.array([
[[0, 0],[1, 1], [0, 0]],
[[1, 1], [0, 0], [0, 0]]
])
我尝试过的:
b = np.where(a == 0, np.array([0, 0]), np.array([1, 1]))
上面的代码给了我一个ValueError: operands could not be broadcast together with shapes (<a's dimentions>) (2,) (2,)
编辑:我这边的例子不好。我认为让它变得简单会使它更具可读性。但是我不一定要 ones
代替 1 和 zeros
代替 0,并且输入不限于 0s 和 1s。相反,我希望输入类似于:
a = np.array([
[0, 1, 0],
[1, 2, 0]
])
输出为:
b = np.array([
[[5, 6],[8, 2], [5, 6]],
[[8, 2], [7, 4], [5, 6]]
])
你可以使用面具和numpy broadcasting
import numpy as np
a = np.array([[0, 1, 0],
[1, 2, 0]])
d = {0: [5, 6],
1: [8, 2],
2: [7, 4]}
# Initialize b
b = np.zeros((a.shape[0], a.shape[1], 2))
for k,v in d.items():
m = a==k
b += m[...,None] * np.tile(v, (a.shape[0], a.shape[1], 1))
b
array([[[5., 6.],
[8., 2.],
[5., 6.]],
[[8., 2.],
[7., 4.],
[5., 6.]]])
您可以扩展维度然后沿新维度重复(或重复然后重塑):
np.repeat(np.expand_dims(a, axis=2), 2, axis=2)
输出:
[[[0 0]
[1 1]
[0 0]]
[[1 1]
[0 0]
[0 0]]]
如果您想要不同的输出,现在您可以更轻松地将您的条件应用于新数组。
更新:针对一般情况对 post 进行的每次编辑:假设您有一个映射字典(取决于您的映射,解决方案可能会有所不同)
map_dict = {0: [5, 6],
1: [8, 2],
2: [7, 4]}
indexer = np.array([map_dict.get(i, [-1,-1]) for i in range(np.amax(a)+1)])[a]
或者在更具体的情况下,如果您的映射包括 0 和 max(a) 之间的所有整数,就像您的示例一样,请使用:
indexer = np.array([map_dict[i] for i in np.unique(a)])[a]
输出:
[[[5 6]
[8 2]
[5 6]]
[[8 2]
[7 4]
[5 6]]]
假设 a
的元素是数组 c
:
In [964]: c = np.array([[5,6], [8,2], [7,4]])
In [965]: a = np.array([[0,1,0],[1,2,0]])
In [966]: c[a,:]
Out[966]:
array([[[5, 6],
[8, 2],
[5, 6]],
[[8, 2],
[7, 4],
[5, 6]]])
这是对您的规范的最简单解释。如果 c
不是像这样的二维数组,或者 a
不只是映射到行,你将不得不做更多的工作来转换它们(并且很可能会丢失大部分 numpy
数组优势).
我要强调这不是 'insert' 或 'in-place' 映射。 a
保持不变。它是一个 (2,3) 数组,Out[966]
是一个 (2,3,2) 数组。