首先看一下where 的简单版本,它可以找到索引:
In [266]: np.where(y=='yo')
Out[266]: (array([ 5, 10], dtype=int32),)
显然你想要y 的所有值,但是用来自x 的一些值替换yo:
In [267]: np.where(y=='yo',x,y)
Out[267]:
array(['', '', '', '', '', '1', '', '', '', '', '5', ''],
dtype='<U11')
y是字符串类型,由于''不能转为数字,所以数字转为字符串。
现在如果 y 是对象 dtype:
In [268]: y = np.array(['', '', '', '', '', 'yo', '', '', '', '', 'yo', '' ],object)
In [269]: np.where(y=='yo')
Out[269]: (array([ 5, 10], dtype=int32),)
In [270]: np.where(y=='yo',x,y)
Out[270]: array(['', '', '', '', '', 1, '', '', '', '', 5, ''], dtype=object)
替换也是对象 dtype,可以混合使用数字和字符串。
在此使用中,所有 3 个术语具有相同的长度。在您的使用中,x 和 y 被替换为标量
In [271]: np.max(x[:3])
Out[271]: 8
In [272]: np.where(y=='yo',8, '')
Out[272]:
array(['', '', '', '', '', '8', '', '', '', '', '8', ''],
dtype='<U11')
In [273]: np.where(y=='yo',8, y)
Out[273]: array(['', '', '', '', '', 8, '', '', '', '', 8, ''], dtype=object)
要插入 9 和 33,您已经找到了收集前 3 个项目的最大值的方法,即运行或滚动最大值。 where 本身无济于事。
accumulate 近似于此(这是cumsum 的“最大”版本)
In [276]: xm=np.maximum.accumulate(x)
In [277]: xm
Out[277]: array([ 0, 2, 8, 9, 9, 9, 12, 12, 33, 33, 33, 33], dtype=int32)
In [278]: np.where(y=='yo',xm, y)
Out[278]: array(['', '', '', '', '', 9, '', '', '', '', 33, ''], dtype=object)
xm 不是前面三个值的最大值,而是前面所有值的最大值。在这种情况下,这是相同的,但通常不会。对于这个x,最后一个值是不同的
这是获得前 3 个最大值的一种方法,诚然有点粗略(通过列表理解):
In [305]: x1=np.concatenate(([0,0],x))
In [306]: xm = [max(x1[i:i+3]) for i in range(0,len(x1))][:len(x)]
In [307]: xm
Out[307]: [0, 2, 8, 9, 9, 9, 12, 12, 33, 33, 33, 11]
In [308]: np.where(y=='yo',xm, y)
Out[308]: array(['', '', '', '', '', 9, '', '', '', '', 33, ''], dtype=object)
带有as_strided的滑动窗口(改编自Numpy: Matrix Array Shift / Insert by Index)
In [317]: xm=np.lib.stride_tricks.as_strided(x1[::-1],shape=(3,12),strides=(-4,-4))
In [318]: xm
Out[318]:
array([[ 3, 5, 11, 33, 4, 12, 1, 4, 9, 8, 2, 0],
[ 5, 11, 33, 4, 12, 1, 4, 9, 8, 2, 0, 0],
[11, 33, 4, 12, 1, 4, 9, 8, 2, 0, 0, 0]])
In [319]: xm.max(axis=0)
Out[319]: array([11, 33, 33, 33, 12, 12, 9, 9, 9, 8, 2, 0])
In [320]: xm = xm.max(axis=0)[::-1]
In [321]: xm
Out[321]: array([ 0, 2, 8, 9, 9, 9, 12, 12, 33, 33, 33, 11])
仅使用 Paul Panzer 的想法yo:
In [29]: idx=np.where(y=='yo')
In [30]: idx
Out[30]: (array([ 5, 10], dtype=int32),)
In [32]: xm = [max(x[i-3:i]) for i in idx[0]]
In [33]: xm
Out[33]: [9, 33]
In [34]: y[idx]=xm
In [35]: y
Out[35]: array(['', '', '', '', '', 9, '', '', '', '', 33, ''], dtype=object)
如果yo 可能出现在前 3 个元素中,我们需要将xm 细化为:
xm = [max(x[max(i-3,0):i+1]) if i>0 else x[i] for i in idx[0]]
否则我们会因尝试获取max([])而出错。