Python 在执行numpy广播操作时应用elementwise规则
我想将两个数值numpy对象Python 在执行numpy广播操作时应用elementwise规则,python,numpy,array-broadcasting,Python,Numpy,Array Broadcasting,我想将两个数值numpy对象t和speed相乘,而不事先知道每个对象是标量还是数组。问题是0是t(或t元素)的法定值,inf是speed(或speed元素)的法定值。我正在使用的模型有一个规则用于这种情况:当速度为无穷大且t为零时,乘积定义为0 我的问题是在应用规则的同时处理两个操作数可能是标量的,可能不是。到目前为止,我能想到的最好办法就是这个丑陋的瀑布: if t.size == 1: if t.flat[0]: t = t * speed else: non
t
和speed
相乘,而不事先知道每个对象是标量还是数组。问题是0是t
(或t
元素)的法定值,inf
是speed
(或speed
元素)的法定值。我正在使用的模型有一个规则用于这种情况:当速度为无穷大且t
为零时,乘积定义为0
我的问题是在应用规则的同时处理两个操作数可能是标量的,可能不是。到目前为止,我能想到的最好办法就是这个丑陋的瀑布:
if t.size == 1:
if t.flat[0]:
t = t * speed
else:
nonzero = t != 0
if speed.size == 1:
t[nonzero] *= speed
else:
t[nonzero] *= speed[nonzero]
我忍不住想,必须有一种更有效、更具Numpythonic的方式,而这正是我所缺少的。有吗?
0*np.inf
抛出一个RuntimeWarning
并计算为np.nan
做乘法,然后替换np.nan
,怎么样
import numpy as np
def multiply(a, b):
temp = np.array(a*b)
temp[np.isnan(temp)] = 0
return temp
测试:
np.random.seed(123)
t = np.random.rand(10)
t[0] = 0
speed = np.random.rand(10)
speed[0] = np.inf
speed[6] = np.inf
输入:
multiply(t, speed)
输出:
array([ 0. , 0.09201602, 0.02440781, 0.49796297, 0.06170694,
0.57372377, inf, 0.03658583, 0.53141369, 0.1746193 ])
已经过了几天了,没有人写下hpaulj和SubhaneilLahiri在评论中给出的答案,所以我最好自己写。我之所以将此作为公认的答案,是因为它具有足够的一般性,足以解决问题的标题,即使在超出问题中给出的特定模型的情况下也是如此
# prepare zeros of the correct shape:
out = np.zeros(np.broadcast(t, speed).shape), dtype=float)
# write the product values into the prepared array, but ONLY
# according to the mask t!=0
np.multiply(t, speed, where=t!=0, out=out)
在问题中的特定模型中,预先准备好的默认输出值0对于测试
t=0
失败:0*速度
在速度
有限的任何地方都是0
,当速度
无限时,它也是法定的0
(根据模型规则)。但这种方法适用于更一般的情况:原则上,可以使用额外的numpy ufunc调用,用任意不同规则的结果填充输出数组的屏蔽部分。如果确实需要,可以抛出“If t.size==1”和相应的“else”条件(外部子句)进入一个列表理解,然后将你的子条件(speed.size案例)放入另一个列表理解。我建议使用numpy操作和广播。使用[np.where]()并利用numpy允许您广播向量运算和其他奇怪的事情的事实。@SachinRaghavendran谢谢,但问题已经从了解广播的位置开始了。在清单中,请注意逻辑树叶子上的三个乘法运算已经(可能)是广播操作。问题是如何在执行此操作时应用特定的0*inf
处理规则。ufunc
类似于multiple take awhere
参数。将其与out
parameter@hpaulj这就是我一直在寻找的答案——一种利用广播功能的更通用的方法,我以前没有这样做过t之前遇到过,与下面warped的答案相反,warped的答案非常有效,但仅适用于本例中的特定规则。您是否愿意将其转换为实际答案,以便我可以接受?willnp.zero(np.broadcast(t,speed).shape)
更好吗?它可读性较差,但可能更有效?嗯,谢谢,是的,我想这对我的情况会有用。进一步的改进是在中使用numpy.errstate(invalid='ignore'):
子句来抑制警告。您还必须说temp=numpy.array(A*b)
而不是temp=a*b
,因为使用索引的后续行在标量情况下不起作用。