将 ndarray 的大多数元素设置为零的好方法是什么?
What's a good way of setting most elements of an ndarray to zero?
我有一个 ndarray
有 10,000 行和 75 列,另一个有相同的行数和 3 列。第二个有整数值。
我想得到一个 10,000 行和 75 列的数组,所有元素都设置为零,除了每行中的元素由第二个数组的相应行中的值索引。
所以从 z_array
和 i_array
开始,我想以 a_array
结束
>>> z_array
array([[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15]])
>>> i_array
array([[0, 2],
[3, 1],
[1, 4],
[2, 3]])
>>> a_array
array([[10, 0, 12, 0, 0, 0],
[ 0, 11, 0, 13, 0, 0],
[ 0, 11, 0, 0, 14, 0],
[ 0, 0, 12, 13, 0, 0]])
我可以看到两种解决方法:要么从一个全为零的数组开始,然后复制 z_array
中的相关元素;或者从 z_array
开始并将所有不相关的元素设置为零。请注意,不相关元素的数量通常远远大于相关元素的数量。
无论哪种方式,是否有进行多项分配的好方法,或者我只需要循环遍历它们?或者有第三种方法吗?
我想知道我是否可以以某种方式使用 numpy.ufunc.at
?
我可以看到如何获取相关元素的索引列表,例如
>>> index_list = [[i, val] for (i, x) in enumerate(i_array) for val in x ]
index_list
[[0, 0], [0, 2], [1, 3], [1, 1], [2, 1], [2, 4], [3, 2], [3, 3]]
对于不相关的元素,获取它们的方法稍微复杂一些。但是这些列表会很大!!
你可以使用 masked arrays
import numpy as np
def mask_array(z_array, i_array):
ROWS, COLS = np.shape(z_array)
# Fill in the mask
mask = np.zeros((ROWS, COLS))
for i in range(ROWS):
np.add.at(mask[i,:], i_array[i], 1)
mask = mask > 0
mask = ~mask
m_array = np.ma.array(z_array, mask=mask, fill_value = 0)
return np.ma.filled(m_array)
a_array = mask_array(z_array, i_array)
为了区分z_array的元素,我定义为:
array([[ 10, 11, 12, 13, 14, 15],
[110, 111, 112, 113, 114, 115],
[210, 211, 212, 213, 214, 215],
[310, 311, 312, 313, 314, 315]])
那么一种可能的解决方案是创建一个用零填充的数组,使用
zeros_like 然后 运行 基于 ndenumerate 方法的循环:
result = np.zeros_like(z_array)
for (r, c), x in np.ndenumerate(i_array):
result[r, x] = z_array[r, x]
对于我的(更改的)源数据,结果是:
array([[ 10, 0, 12, 0, 0, 0],
[ 0, 111, 0, 113, 0, 0],
[ 0, 211, 0, 0, 214, 0],
[ 0, 0, 312, 313, 0, 0]])
您似乎在寻找类似于 np.put_along_axis
的内容
以你那里的例子为例,如果你运行:np.put_along_axis(z_array, i_array, 0, axis=1)
z_array = [[ 0 11 0 13 14 15]
[10 0 12 0 14 15]
[10 0 12 13 0 15]
[10 11 0 0 14 15]]
输出与你想要的相反。
要获得您想要的内容,请将 z_array
的副本创建为 a_array
。然后,比较这些矩阵并保留 z_array
元素非零的值。
a_array = copy.copy(z_array)
np.put_along_axis(z_array, i_array, 0, axis=1)
a_array[(z_array != 0)] = 0
这给出了您预期的输出:
a_array = [[10 0 12 0 0 0]
[ 0 11 0 13 0 0]
[ 0 11 0 0 14 0]
[ 0 0 12 13 0 0]]
np.put_along_axis
documentation
查看此 以了解更多组合矩阵的选项 (np.where
)
我有一个 ndarray
有 10,000 行和 75 列,另一个有相同的行数和 3 列。第二个有整数值。
我想得到一个 10,000 行和 75 列的数组,所有元素都设置为零,除了每行中的元素由第二个数组的相应行中的值索引。
所以从 z_array
和 i_array
开始,我想以 a_array
>>> z_array
array([[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15],
[10, 11, 12, 13, 14, 15]])
>>> i_array
array([[0, 2],
[3, 1],
[1, 4],
[2, 3]])
>>> a_array
array([[10, 0, 12, 0, 0, 0],
[ 0, 11, 0, 13, 0, 0],
[ 0, 11, 0, 0, 14, 0],
[ 0, 0, 12, 13, 0, 0]])
我可以看到两种解决方法:要么从一个全为零的数组开始,然后复制 z_array
中的相关元素;或者从 z_array
开始并将所有不相关的元素设置为零。请注意,不相关元素的数量通常远远大于相关元素的数量。
无论哪种方式,是否有进行多项分配的好方法,或者我只需要循环遍历它们?或者有第三种方法吗?
我想知道我是否可以以某种方式使用 numpy.ufunc.at
?
我可以看到如何获取相关元素的索引列表,例如
>>> index_list = [[i, val] for (i, x) in enumerate(i_array) for val in x ]
index_list
[[0, 0], [0, 2], [1, 3], [1, 1], [2, 1], [2, 4], [3, 2], [3, 3]]
对于不相关的元素,获取它们的方法稍微复杂一些。但是这些列表会很大!!
你可以使用 masked arrays
import numpy as np
def mask_array(z_array, i_array):
ROWS, COLS = np.shape(z_array)
# Fill in the mask
mask = np.zeros((ROWS, COLS))
for i in range(ROWS):
np.add.at(mask[i,:], i_array[i], 1)
mask = mask > 0
mask = ~mask
m_array = np.ma.array(z_array, mask=mask, fill_value = 0)
return np.ma.filled(m_array)
a_array = mask_array(z_array, i_array)
为了区分z_array的元素,我定义为:
array([[ 10, 11, 12, 13, 14, 15],
[110, 111, 112, 113, 114, 115],
[210, 211, 212, 213, 214, 215],
[310, 311, 312, 313, 314, 315]])
那么一种可能的解决方案是创建一个用零填充的数组,使用 zeros_like 然后 运行 基于 ndenumerate 方法的循环:
result = np.zeros_like(z_array)
for (r, c), x in np.ndenumerate(i_array):
result[r, x] = z_array[r, x]
对于我的(更改的)源数据,结果是:
array([[ 10, 0, 12, 0, 0, 0],
[ 0, 111, 0, 113, 0, 0],
[ 0, 211, 0, 0, 214, 0],
[ 0, 0, 312, 313, 0, 0]])
您似乎在寻找类似于 np.put_along_axis
以你那里的例子为例,如果你运行:np.put_along_axis(z_array, i_array, 0, axis=1)
z_array = [[ 0 11 0 13 14 15]
[10 0 12 0 14 15]
[10 0 12 13 0 15]
[10 11 0 0 14 15]]
输出与你想要的相反。
要获得您想要的内容,请将 z_array
的副本创建为 a_array
。然后,比较这些矩阵并保留 z_array
元素非零的值。
a_array = copy.copy(z_array)
np.put_along_axis(z_array, i_array, 0, axis=1)
a_array[(z_array != 0)] = 0
这给出了您预期的输出:
a_array = [[10 0 12 0 0 0]
[ 0 11 0 13 0 0]
[ 0 11 0 0 14 0]
[ 0 0 12 13 0 0]]
np.put_along_axis
documentation
查看此 np.where
)