按元素乘法忽略矩阵的某些行
Elementwise multiplication ignoring certain rows of a matrix
假设我有一个这样的矩阵:
import numpy as np
a = np.array([[1, 2, 3], [89, 43, 2], [12, -3, 4], [-2, 4, 7]])
array([[ 1, 2, 3],
[89, 43, 2],
[12, -3, 4],
[-2, 4, 7]])
和一个看起来像这样的矢量:
b = np.array([1, 2, 3])
如果我现在想做一个元素乘法,我可以简单地做
c = a * b
并获得
array([[ 1, 4, 9],
[89, 86, 6],
[12, -6, 12],
[-2, 8, 21]])
我的问题是:我怎样才能只对矩阵中的某些行进行这种乘法运算?我目前是这样做的:
E = a.copy()
# ignore these rows
ignInd = [1, 3]
for ind in xrange(a.shape[0]):
if ind not in ignInd:
E[ind, :] = a[ind, :] * b
矩阵 E
看起来很理想(第 1 行和第 3 行与 a
中的相同):
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
有人能想出比这更聪明的解决方案吗?
您可以直接用另一个 NumPy 数组索引一个 NumPy 数组。在你的例子中,你有你想要忽略的行的索引,所以你可以构建一个索引数组到 include 从这个:
In [21]: ignInd = [1,3] #ignore these rows
In [22]: ind = np.array([i for i in range(a.shape[0]) if i not in ignInd])
In [23]: E2 = a.copy()
In [24]: E2[ind,:] = a[ind,:]*b
In [25]: E2
Out[25]:
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
编辑:正如@DSM 评论的那样,对于大型数组,使用 NumPy 的矢量化方法构建索引数组会更有效,即。 ind = np.setdiff1d(np.arange(len(a)), ignInd)
而不是上面使用的列表理解。
对于 a
中的第一行
a[0] = a[0] * b
..其他行依此类推。
看来你可以只做乘法,然后把原始数据放回你想忽略的地方...
>>> import numpy as np
>>> a = np.array([[1,2,3],[89,43,2],[12, -3, 4], [-2, 4, 7]])
>>> b = np.array([1,2,3])
>>> c = a * b
>>> ignInd = [1,3]
>>> c[ignInd, :]
array([[89, 86, 6],
[-2, 8, 21]])
>>> c[ignInd, :] = a[ignInd, :]
>>> c
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
您可以使用 boolean indexing
with np.in1d
来 select 在给定索引列表中排除的行。实现看起来像这样 -
E = a.copy()
mask = ~np.in1d(np.arange(a.shape[0]),ignInd,)
E[mask] = a[mask]*b
假设我有一个这样的矩阵:
import numpy as np
a = np.array([[1, 2, 3], [89, 43, 2], [12, -3, 4], [-2, 4, 7]])
array([[ 1, 2, 3],
[89, 43, 2],
[12, -3, 4],
[-2, 4, 7]])
和一个看起来像这样的矢量:
b = np.array([1, 2, 3])
如果我现在想做一个元素乘法,我可以简单地做
c = a * b
并获得
array([[ 1, 4, 9],
[89, 86, 6],
[12, -6, 12],
[-2, 8, 21]])
我的问题是:我怎样才能只对矩阵中的某些行进行这种乘法运算?我目前是这样做的:
E = a.copy()
# ignore these rows
ignInd = [1, 3]
for ind in xrange(a.shape[0]):
if ind not in ignInd:
E[ind, :] = a[ind, :] * b
矩阵 E
看起来很理想(第 1 行和第 3 行与 a
中的相同):
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
有人能想出比这更聪明的解决方案吗?
您可以直接用另一个 NumPy 数组索引一个 NumPy 数组。在你的例子中,你有你想要忽略的行的索引,所以你可以构建一个索引数组到 include 从这个:
In [21]: ignInd = [1,3] #ignore these rows
In [22]: ind = np.array([i for i in range(a.shape[0]) if i not in ignInd])
In [23]: E2 = a.copy()
In [24]: E2[ind,:] = a[ind,:]*b
In [25]: E2
Out[25]:
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
编辑:正如@DSM 评论的那样,对于大型数组,使用 NumPy 的矢量化方法构建索引数组会更有效,即。 ind = np.setdiff1d(np.arange(len(a)), ignInd)
而不是上面使用的列表理解。
对于 a
中的第一行a[0] = a[0] * b
..其他行依此类推。
看来你可以只做乘法,然后把原始数据放回你想忽略的地方...
>>> import numpy as np
>>> a = np.array([[1,2,3],[89,43,2],[12, -3, 4], [-2, 4, 7]])
>>> b = np.array([1,2,3])
>>> c = a * b
>>> ignInd = [1,3]
>>> c[ignInd, :]
array([[89, 86, 6],
[-2, 8, 21]])
>>> c[ignInd, :] = a[ignInd, :]
>>> c
array([[ 1, 4, 9],
[89, 43, 2],
[12, -6, 12],
[-2, 4, 7]])
您可以使用 boolean indexing
with np.in1d
来 select 在给定索引列表中排除的行。实现看起来像这样 -
E = a.copy()
mask = ~np.in1d(np.arange(a.shape[0]),ignInd,)
E[mask] = a[mask]*b