Python 在执行numpy广播操作时应用elementwise规则

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

我想将两个数值numpy对象
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 a
where
参数。将其与
out
parameter@hpaulj这就是我一直在寻找的答案——一种利用广播功能的更通用的方法,我以前没有这样做过t之前遇到过,与下面warped的答案相反,warped的答案非常有效,但仅适用于本例中的特定规则。您是否愿意将其转换为实际答案,以便我可以接受?will
np.zero(np.broadcast(t,speed).shape)
更好吗?它可读性较差,但可能更有效?嗯,谢谢,是的,我想这对我的情况会有用。进一步的改进是在
中使用numpy.errstate(invalid='ignore'):
子句来抑制警告。您还必须说
temp=numpy.array(A*b)
而不是
temp=a*b
,因为使用索引的后续行在标量情况下不起作用。