【问题标题】:Python 3.7 boolean indexing *warning* using 'list'Python 3.7 boolean indexing *warning* using 'list'
【发布时间】:2019-08-06 23:03:27
【问题描述】:
  • 获取一个非常大的列表,由于各种原因,它和所有其他的都无法放入可用内存中,这里:A = [ 2, -3, 10, 0.2]
  • 映射其组件的符号:sign_A = list(map(lambda u: (abs(u)==u), A))
    你得到[True, False, True, True]
  • 在需要操作abs_A = [abs(e) for e in A] 的地方做一些逻辑。所以你刷新A 并继续使用sign_Aabs_A。该逻辑产生组件的感兴趣索引,例如ik、...对于列表abs_A

我遇到的问题是当使用三元运算符(falsevalue, truevalue)[condition]Asigned 分量进行一些代数时,例如:

abs_A[i]*(-1, 1)[sign_A[i]] + abs_A[k]**(-1, 1)[sign_A[k]]
# equivalently, can use:
# abs_A[i]*(-1, 1)[np.bool(sign_A[i])] + abs_A[k]**(-1, 1)[np.bool(sign_A[k])]

我收到此警告:

DeprecationWarning:将来,'np.bool_' 将是一个错误 标量被解释为索引。

警告间接告诉我,可能有比我的 sn-p 更好、更“pythonesque”的方式来执行此操作。我找到了相关的帖子(例如herehere),但没有关于我应该如何处理它的建议。有人指点吗?

【问题讨论】:

  • 只需将np.bool() 替换为int()abs_A[i]*(-1, 1)[int(sign_A[i])]+...
  • A 看起来像一个列表,而不是一个数组。
  • @DYZ:我刚刚在 stackoverflow.com/questions/26282266/… 上阅读 Jaime 的评论,建议相同。发送。
  • sign_A 的元素已经是布尔值;它们在索引 (-1,1) 之类的元组时起作用。
  • @hpaulj:确实如此,而且确实如此。但是,当使用它们以黑色显示(在 sn-p 中)时,我得到与将它们与内置 boolnp_bool 一起使用时相同的错误。我是 Python 的新手,这让我很失望。

标签: python-3.x numpy boolean


【解决方案1】:

使用列表,布尔索引可以正常工作:

In [21]: A = [ 2, -3, 10, 0.2]                                                  
In [22]: sign_A = list(map(lambda u: (abs(u)==u), A))                           
In [23]: abs_A = [abs(e) for e in A]                                            
In [24]: i=0; k=1                                                               
In [25]: abs_A[i]*(-1, 1)[sign_A[i]] + abs_A[k]**(-1, 1)[sign_A[k]]             
Out[25]: 2.3333333333333335

如果我们尝试使用 numpy 布尔值进行索引,我们确实会收到警告:

In [26]: abs_A[i]*(-1, 1)[np.array(sign_A)[i]]                                  
/usr/local/bin/ipython3:1: DeprecationWarning: In future, it will be an error for 'np.bool_' scalars to be interpreted as an index
  #!/usr/bin/python3
Out[26]: 2

我们可以通过从一开始就将 sign_A 数组设为整数来解决这个问题:

In [27]: abs_A[i]*(-1, 1)[np.array(sign_A,dtype=int)[i]]                        
Out[27]: 2

如果我们从一个数组开始:

In [28]: B = np.array(A)                                                        

符号数组 - 使用 where 直接映射到 (-1,1) 空间

In [30]: sign_B = np.where(B>=0,1,-1)                                           
In [31]: sign_B                                                                 
Out[31]: array([ 1, -1,  1,  1])

abs 数组:

In [32]: abs_B = np.abs(B)                                                      

重新创建的数组:

In [33]: abs_B*sign_B                                                           
Out[33]: array([ 2. , -3. , 10. ,  0.2])

【讨论】:

  • +1:@hpaulj:对我来说,布尔索引会引发指示的警告(根据我的 OP 和您的输出 [26])。我从您非常具有教育意义的回答(非常感谢)中看到您使用的是 Jupyter 笔记本。不同的 linter 能否解释行为上的奇怪差异?我在vim 上并在语法的不同方面使用pylintflake8 和/或bandit(我不只是堆积了3 个短绒)...
  • 我的警告来自numpy,而不是 lint。 1.16.1
【解决方案2】:

为避免警告,请将np.bool() 替换为int()

abs_A[i]*(-1, 1)[int(sign_A[i])] + ...

【讨论】:

    【解决方案3】:

    这里一个简单的解决方案是使用语法truevalue if condition else falsevalue 代替(falsevalue, truevalue)[condition]

    【讨论】:

      【解决方案4】:

      DYZ 从 2019 年 3 月 15 日开始扩展答案:

      在这种情况下,将符号函数从布尔值重新映射为整数导致使用 np.bool 触发

      DeprecationWarning:将来,'np.bool_' 将是一个错误 标量被解释为索引。

      改用int() 解决了这个问题。

      包装方法可读性较差,但也可以:int(np.bool(sign_A[i]))

      在更一般的 numpy 按位逻辑运算符的情况下,同样的警告会被触发,例如,使用不等式检查作为索引:

      result = X[np.less_equal(a, b)] 
      

      X 可以保存整数以外的类型的项目。

      如果 X 包含 float 项,一个合适的解决方案是:

      result = float(X[np.less_equal(a, b)])
      

      或者,

      result = X[np.less_equal(a, b)] 
      return = float(result)
      

      可以与函数定义一起使用。

      后一种return 表单是我解决今天在函数定义中触发的警告的方式。 DYZ的回答给了我指导。

      【讨论】:

        猜你喜欢
        • 2021-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-27
        • 1970-01-01
        • 1970-01-01
        • 2019-04-02
        • 2020-05-30
        相关资源
        最近更新 更多