【问题标题】:Apply conditional function to every element of a numpy array [duplicate]将条件函数应用于numpy数组的每个元素[重复]
【发布时间】:2020-08-16 03:20:44
【问题描述】:

我有这个功能:

if elem < 0:
    elem = 0
else:
    elem = 1

我想将此函数应用于 NumPy 数组中的每个元素,当仅针对相同维度执行此函数时,可以使用 for loop 来完成。但在这种情况下,无论数组尺寸和形状如何,我都需要它工作。有什么方法可以在 Python 中使用 NumPy 实现吗?

或者是否有任何通用方法可以将任何def 应用于 NumPy n 维数组中的每个元素?

【问题讨论】:

标签: python numpy


【解决方案1】:

你可以这样做:

import numpy as np

a=np.array([-2,-1,0,1,2])

a[a>=0]=1
a[a<0]=0

>>> a
array([0, 0, 1, 1, 1])

【讨论】:

    【解决方案2】:

    np.where

    np.where(arr < 0, 0, 1)
    

    【讨论】:

      【解决方案3】:

      不是吗

      arr = (arr >= 0).astype(int)
      

      【讨论】:

        【解决方案4】:

        使用 numpy.vectorize():

        import numpy as np
        
        def unit(elem):
            if elem < 0:
                elem = 0
            else:
                elem = 1
        a = np.array([[1, 2, -0.5], [0.5, 2, 3]])
        vfunc = np.vectorize(unit)
        vfunc(a)
        
        # array([[1, 1, 0], [1, 1, 1]])
        

        【讨论】:

        • 这很慢...
        • 我做到了。这里不适合使用vectorize
        【解决方案5】:

        您可以使用布尔掩码来定义决策数组。让我们通过一个具体的例子来工作。您有一个正数和负数数组,并且您只想在正数位置取平方根:

        arr = np.random.normal(size=100)
        

        你计算一个类似的掩码

        mask = arr >= 0
        

        应用掩码最直接的方法是创建一个输出数组,并填写所需的元素:

        result = np.empty(arr.shape)
        result[mask] = np.sqrt(arr[mask])
        result[~mask] = arr[~mask]
        

        这不是超级高效,因为您必须计算掩码的逆并多次应用它。对于这个特定示例,您可以利用 np.sqrtufunc 的事实并使用其 where keyword

        result = arr.copy()
        np.sqrt(arr, where=mask, out=result)
        

        应用蒙版的一种流行方法是使用np.where,但我特意构建了这个示例来说明注意事项。最简单的方法是计算

        result = np.where(mask, np.sqrt(arr), arr)
        

        where 根据mask 是否为真,从np.sqrt(arr)arr 中选择值。在许多情况下,这是一种非常好的方法,但您必须为两个分支预先计算值,这正是平方根要避免的。

        TL;DR

        您的具体示例是寻找掩码本身的表示。如果你不关心类型:

        result = arr >= 0
        

        如果您确实关心类型:

        result = (arr >= 0).astype(int)
        

        result = -np.clip(arr, -1, 0)
        

        这些解决方案会创建与输入不同的数组。如果要替换同一缓冲区中的值,

        mask = arr >= 0
        arr[mask] = 1
        arr[~mask] = 0
        

        【讨论】:

          【解决方案6】:

          上述解决方案的替代方案是将列表理解与三元运算符相结合。

          my_array = np.array([-1.2, 3.0, -10.11, 5.2])
          sol = np.asarray([0 if val < 0 else 1 for val in my_array])
          

          看看这些来源 https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions https://book.pythontips.com/en/latest/ternary_operators.html

          【讨论】:

            猜你喜欢
            • 2016-08-19
            • 1970-01-01
            • 1970-01-01
            • 2016-08-10
            • 1970-01-01
            • 2020-12-31
            • 1970-01-01
            • 2020-06-06
            • 2014-10-17
            相关资源
            最近更新 更多