我有一维数组,例如:
>>> 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
的条件,这又涉及许多不必要的操作,因为只有该数组的一小部分是有趣的。
是否有更有效的方法根据索引数组修改数组,以及减少不必要操作量的条件?
换句话说:上面的两个解决方法既有利也有弊。第一种方法消除了不必要的条件检查,但(可能)涉及不必要的复制。第二种方法消除了不必要的复制,但(可能)涉及不必要的条件检查。那么是否有一种方法结合了两种方法的优点,从而消除了不必要的复制和不必要的条件检查?
答案 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
}
}