我有两个数组U
和V
,两者都是形状( f , m )。我将在下面的示例中设置 f = 4, m = 3.
我想提取U
每列的最小值,但V
中的相应值是非负的,即对于第j列,我想返回最小值{ U[i,j]
,V[i,j] > 0
。
我的第一次尝试是:
import numpy as np
U = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
V = np.array([[1,-1,1],[1,1,1],[-1,-1,1],[-1,-1,1]])
mask = (V > 0)
np.amin(U[mask], axis = 0)
但这会返回1(整个数组的最小值),而不是[1,5,3]
,即我正在寻找的条件列式最小值。
似乎我的问题是U[mask]
变平了形状(1,7),它破坏了(4,3)结构,并且使得搜索列式最小化是不可能的(显然)。 / p>
我有没有办法修改此代码,以便我可以返回我想要的列数最小值?
答案 0 :(得分:3)
这听起来像是masked arrays的任务:
np.amin(np.ma.masked_array(U, V <= 0), axis=0)
让我们比较一下拟议方法的表现:
import numpy as np
from time_stats import compare_calls
U = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
V = np.array([[1,-1,1],[1,1,1],[-1,-1,1],[-1,-1,1]])
def masked(U=U, V=V):
return np.amin(U[mask], axis = 0)
def where1(U=U, V=V):
mask = np.where(V[:,:] < 0, np.inf, 1)
return np.amin(U*mask, axis = 1)
def where2(U=U, V=V):
np.where(V>0, U, np.iinfo(int).max).min(axis=0)
r = compare_calls(['masked()', 'where1()', 'where2()'], globals=globals())
print(r)
r.hist()
# masked() : 0.0001 s/call median, 9.7e-05 ... 0.00016 IQR
# where1() : 1e-05 s/call median, 1e-05 ... 1.1e-05 IQR
where2() : 9.6e-06 s/call median, 9.1e-06 ... 1e-05 IQR
使用where
明显比这个矩阵大小的掩码数组快:)
大矩阵的差异越小,但@PaperPanzer的解决方案总是最快。
E.g。对于1000x1000矩阵:
# masked() : 0.015 s/call median, 0.015 ... 0.016 IQR
# where1() : 0.017 s/call median, 0.017 ... 0.02 IQR
# where2() : 0.011 s/call median, 0.01 ... 0.013 IQR
答案 1 :(得分:3)
您可以将iinfo
与np.where(V>0, U, np.iinfo(int).max).min(axis=0)
# array([1, 5, 3], dtype=int64)
一起使用:
np.inf
np.where(V>0, U, np.inf).min(axis=0)
# array([1., 5., 3.])
不是一个整数,因此会强制进行不合需要的上传。
np.iinfo(int)
# iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
np.where(V>0, U, np.iinfo(int).max)
# array([[ 1, 9223372036854775807, 3],
# [ 4, 5, 6],
# [9223372036854775807, 9223372036854775807, 9],
# [9223372036854775807, 9223372036854775807, 12]],
# dtype=int64)
步骤一步:
% empty List
chop_up([], []).
% single item list
chop_up([X], [X]).
% continue if the first number is not part of a sequence
chop_up(List, NewList):-
List = [First | Tail],
Tail = [Second | _],
First =\= Second - 1,
chop_up(Tail, NewList2),
NewList = [First | NewList2].
% if it is part of a sequence
chop_up(List, NewList):-
List = [First | Tail],
Tail = [Second | Tail2],
First is Second - 1,
chop_up(Tail, NewList2),
NewList = [[First] | NewList2].
答案 2 :(得分:2)
可能不是最漂亮的解决方案,但它有效; - )
mask = np.where(V[:,:] < 0, np.inf, 1)
x = np.amin(U*mask, axis = 1)