从这开始:
import numpy as np
x = np.array([0, 2, 8, 9, 4, 1, 12, 4, 33, 11, 5, 3 ])
y = np.array(['', '', '', '', '', 'yo', '', '', '', '', 'yo', '' ])
i = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ])
print np.amax(x[:3] )
print np.amin(x[:3] )
尝试使用numpy.where
获取前三个项目的最大值或最小值。所以,本质上是试图使用数组中的“索引”
np.where
。如果有更高性能的方法,请显示。
对此进行了尝试:
np.where(y == "yo", np.amax(x[:3] ) ,"")
结果(为什么它返回一个字符串?):
array(['', '', '', '', '', '8', '', '', '', '', '8', ''],
dtype='|S21')
想:
array(['', '', '', '', '', 9, '', '', '', '', 33, ''],
dtype='|S21')
答案 0 :(得分:2)
首先看一下where
的更简单版本,它找到索引:
In [266]: np.where(y=='yo')
Out[266]: (array([ 5, 10], dtype=int32),)
显然,你想要y
的所有版本,但用yo
中的某个值替换x
:
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)
如果前3个元素中可能出现yo
,我们需要使用以下内容优化xm
:
xm = [max(x[max(i-3,0):i+1]) if i>0 else x[i] for i in idx[0]]
否则我们会因尝试max([])
而感到错误。
答案 1 :(得分:0)
“我想要的”项目,我担心你不能拥有,因为你不能在字符串dtype数组中包含数字。您正在使用它的形式where
将其最后两个参数“混合”到一个数组中。为此,它必须选择一个dtype。由于
>>> np.can_cast(str, int)
False
>>> np.can_cast(int, str)
True
所以str是两个参数'dtypes / types之一,可以容纳两个参数的值。
除了数据类型之外,您可能希望查看scipy.ndimage.maximum_filter
:
>>> scipy.ndimage.maximum_filter(x, 3)
array([ 2, 8, 9, 9, 9, 12, 12, 33, 33, 33, 11, 5])
您可能需要修改偏移量以满足您的要求。
答案 2 :(得分:0)
不确定我理解你想要什么,但这有助于:
x = np.sort(x)
sel = np.where(y=="yo")[0]
y[sel] = x[-len(sel):]
?