根据索引数组和条件

时间:2017-06-29 18:55:32

标签: python numpy

情况

我有一维数组,例如:

>>> a
array([  0.,   1.,  nan,  nan,   4.,  nan,   6.,  nan,   8.,   9.])

我还有一个索引数组,用于指示a的相关部分,例如:

>>> index
array([0, 2, 4, 6, 8])

现在,我想要修改a 所指向的index部分,这些部分符合特定条件,即numpy.isnan(将它们设置为零)。

因为index array的副本被退回,我不能简单地使用

>>> sub = a[index]
>>> sub[numpy.isnan(sub)] = 0

这只会修改副本sub,但不会修改原始数组。

的变通方法

反向复制sub

将更新的数组sub复制到a[index]

>>> sub[numpy.isnan(sub)] = 0
>>> a[index] = sub

但是如果子数组很大且只有少数元素被更新,那么这会有很多不必要的复制。

创建组合掩码

我可以通过

将索引数组转换为布尔数组
>>> mask = numpy.zeros(a.size, dtype=bool)
>>> mask[index] = True

并通过

更新原始数组
>>> a[mask & numpy.isnan(a)] = 0

同样,我可以通过

创建一个组合索引数组
>>> mask = numpy.intersect1d(index, numpy.where(numpy.isnan(a)), assume_unique=True)
>>> a[mask] = 0

然而,两种方法都涉及检查整个数组a的条件,这又涉及许多不必要的操作,因为只有该数组的一小部分是有趣的。

问题

是否有更有效的方法根据索引数组修改数组,以及减少不必要操作量的条件?

换句话说:上面的两个解决方法既有利也有弊。第一种方法消除了不必要的条件检查,但(可能)涉及不必要的复制。第二种方法消除了不必要的复制,但(可能)涉及不必要的条件检查。那么是否有一种方法结合了两种方法的优点,从而消除了不必要的复制和不必要的条件检查?

2 个答案:

答案 0 :(得分:2)

一种选择是提取a[index]来测试谓词,选择index的匹配值,然后再次索引:

a[index[np.isnan(a[index])]] = 0

但是,您可能希望测试您对哪些操作实际上会很昂贵的期望。不必要的谓词测试或不必要的副本可能不会那么昂贵,如果您要使用NumPy,您将不得不习惯于不必要的副本。 NumPy喜欢它的巨型划痕阵列。

答案 1 :(得分:0)

您可以编写自己的循环:迭代相关索引,检查这些位置的数组元素,并在必要时更新它们。

func emailSingUp(){
    guard let email = emailTextField.text, let password = passwordTextField.text,let name = nameTextField.text else {
        print("unsuccessful signup")
        return
    }
    Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
        if error != nil{
            print(error!)
            return
        }else{
let values = ["name":name, "email":email]
Database.database().reference().child("users").child("\(Auth.auth().currentUser!.uid)").updateChildValues(values) { (err, ref) in
    if err != nil{
        print(err!)
        return
    }
    }