amin内的条件

时间:2018-03-29 11:19:02

标签: python numpy conditional min

我有两个数组UV,两者都是形状( 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>

我有没有办法修改此代码,以便我可以返回我想要的列数最小值?

3 个答案:

答案 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

enter image description here

使用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)

您可以将iinfonp.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)