【问题标题】:numpy where takes at most 3 arguments - a way around this?numpy where 最多需要 3 个参数 - 解决这个问题的方法?
【发布时间】:2017-06-16 16:10:41
【问题描述】:

假设我有这个代码:

import numpy as np

def myf(c):
    return c*11

def method_A(c):
    return c*999

def method_B(c):
    return c*55

minimum = 30
maximum = 100
the_method = 'A'

b = np.array([1, 20, 35, 3, 45, 52, 78, 101, 127, 135])

我想使用 numpy where 来满足一些条件。

类似:

b = np.where( np.logical_or(b < minimum , b > maximum) , b, 
             (if the_method == 'A': method_A(b)) ,
             (if the_method == 'B': method_B(b)))

如果满足b &lt; min or b &gt; max条件,则将b中的每个元素保持原样,否则if the_method is A , call method A否则if method is B, call method B

所以,我试过了:

b = np.where( np.logical_or(b < minimum , b > maximum) , b, 
             (np.where(the_method == 'A',method_A(b),b)),
             (np.where(the_method == 'B',method_B(b),b))
            )

这给了我function takes at most 3 arguments (4 given),因为 np.where 不能接受超过 3 个参数。

有没有办法解决我的问题?

【问题讨论】:

  • 内部where 周围是否需要额外的括号?像这样:In [20]: b = np.where( np.logical_or(b &lt; minimum , b &gt; maximum) , b, ((np.where(the_method == 'A',method_A(b),b)), (np.where(the_method == 'B',method_B(b),b))) ) b Out[20]: array([[ 1, 20, 34965, 3, 44955, 51948, 77922, 101, 127, 135], [ 1, 20, 35, 3, 45, 52, 78, 101, 127, 135]])?
  • 嗯..是的!我只想要一个数组作为输出,而不是两个。
  • np.where 及其三个参数实现 IF-ELSE,而您有两个 IF。所以,我不确定np.where在这里是否是一个不错的选择。
  • @EdChum:嗯,好的!我只是打开括号并使用((np.where(apply_method == 'A',method_A(b), (np.where(apply_method == 'B',method_B(b),None)),它工作正常!如果你想把它作为答案,谢谢
  • 您发布的 sn-p 不起作用,apply_method 未定义

标签: python numpy


【解决方案1】:

您的括号不平衡,您需要在内部条件中添加额外的括号:

In [33]:
b = np.where( np.logical_or(b < minimum , b > maximum) , b,
             ((np.where(apply_method == 'A',method_A(b),
             (np.where(apply_method == 'B',method_B(b),None))
            ))))
b

Out[33]:
array([1, 20, 35000, 3, 45000, 52000, 78000, 101, 127, 135], dtype=object)

您的初次尝试:

b = np.where( np.logical_or(b < minimum , b > maximum) , b, 
             (np.where(the_method == 'A',method_A(b),b)),
             (np.where(the_method == 'B',method_B(b),b))
            )

其他条件需要括号

【讨论】:

  • 注意威胁插入 None 在这里造成的性能成本 - 数组现在是 dtype=object
【解决方案2】:

the_method 是一个标量而不是一个数组,所以这里不需要内部的np.wheres:

if the_method == 'A':
    which_method = method_A 
elif the_method == 'B':
    which_method = method_B 
else:
    raise ValueError

b = np.where(
    (b < minimum) | (b > maximum),
     b, 
     which_method(b)
)

事实上,如果你在这两种方法中都插入一个print,你会看到比使用np.where时,它们都运行了。

如果你真的打算用一种表达方式做到这一点:

def _raise(x): raise x

b = np.where(
    (b < minimum) | (b > maximum),
     b, 
     (
         method_A if the_method == 'A' else
         method_B if the_method == 'B' else
         _raise(ValueError)
     )(b)
)

【讨论】:

    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    相关资源
    最近更新 更多