如何在没有循环控制结构的函数列表中评估数字数组?

时间:2017-04-13 09:35:28

标签: python arrays numpy vectorization

给出一系列要点:

import numpy as np
x = np.array([1,2,3,4])

和一系列功能:

f = [lambda x:x>2,lambda x: x==2]

xf的长度是任意的。我想知道,xi(在x中)满足f中的所有函数。这是我的代码:

import numpy as np

def search(x, f):
    finalList = [] # Final list that contains the results
    r = []
    for i in range(len(f)):
         r.append(f[i](x)) # Evaluate all x's over ith function 
    np.array(r)
    r = np.transpose(r)
    for i in range(len(r)):
        finalList.append(i) if np.all(r[i]) else False
    return finalList

我知道我的算法是天真的(但有效)可能有不必要的步骤,但有没有办法避免for循环在这里或有更好的方法吗?

3 个答案:

答案 0 :(得分:0)

如果我明白你的需要,也许你可以这样做:

import numpy as np
x = np.array([1,2,3,4])
f = [lambda x: x>2,lambda x: x==2]
result = [i for i in x if all([fun(i) for fun in f])]

如果你想返回元素的位置而不是元素:

result = [e for e, i in enumerate(x) if all([fun(i) for fun in f])]

答案 1 :(得分:0)

这里有两个没有循环的解决方案,适用于任意数量的函数:

解决方案1(一个班轮):

result = x[reduce(lambda y, z: y & z, map(lambda cond: cond(x), f))]

解决方案2:

import numpy as np
x = np.array([1,2,3,4])
f = [lambda x:x>2,lambda x: x==2]

each_cond = map(lambda cond: filter(cond, x), f)

def list_intersection(it_list):
    sets = iter(map(set, it_list))
    result = sets.next()
    for s in sets:
        result = result.intersection(s)
    return list(result)

result = list_intersection(each_cond)

答案 2 :(得分:0)

另一种直截了当的方法是使用

for fn in f:
    res = np.apply_along_axis(fn, -1, x)
    # do further stuff & return

但是,为什么你想要一个功能列表?是不是不可能在这样的单一条件下做到这一点?

In [15]: x
Out[15]: array([1, 2, 3, 4])

In [16]: (x > 2) & (x == 2)
Out[16]: array([False, False, False, False], dtype=bool)

# or combining everything
In [18]: np.all((x > 2) & (x == 2))
Out[18]: False