简体   繁体   English

使用Numpy.where从基于另一个数组的数组中获取Max / Min

[英]Get Max/Min from array based on another array using Numpy.where

Starting with this: 从这开始:

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] )        

Trying to get the max or min value for the prior three items using numpy.where . 尝试使用numpy.where获取前三个项目的最大值或最小值。 So, in essence trying to use the "index" of array within the np.where . 所以,本质上是试图在np.where使用数组的“索引”。 If there a more performant way to do this, please show. 如果有更高性能的方法,请显示。

Tried variations on this: 对此进行了尝试:

np.where(y == "yo", np.amax(x[:3] ) ,"")

result (why is it returning a string?): 结果(为什么它返回一个字符串?):

array(['', '', '', '', '', '8', '', '', '', '', '8', ''], 
      dtype='|S21')

wanted: 通缉:

 array(['', '', '', '', '', 9, '', '', '', '', 33, ''], 
      dtype='|S21')

First look at the simpler version of where , which finds the indices: 首先看一下where的更简单版本,它找到索引:

In [266]: np.where(y=='yo')
Out[266]: (array([ 5, 10], dtype=int32),)

Evidently you want all the valyes for y , but replacing the yo with some value from x : 显然你想要y所有valyes,但用x某个值替换yo

In [267]: np.where(y=='yo',x,y)
Out[267]: 
array(['', '', '', '', '', '1', '', '', '', '', '5', ''], 
      dtype='<U11')

y is string type, and since '' can't be converted to a number, the numbers are converted to string. y是字符串类型,由于''无法转换为数字,因此数字将转换为字符串。

Now if y was object dtype: 现在如果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)

the replacement is also object dtype and can have a mix of numbers and strings. 替换也是对象dtype,可以混合使用数字和字符串。

In this use all 3 terms have the same length. 在这种使用中,所有3个术语具有相同的长度。 In your use, x and y are replaced with scalars 在您的使用中, xy被替换为标量

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)

To insert 9 and 33 you have figure out some way of collecting the max of the previous 3 items, ie a running or rolling max. 要插入933你已经找到了收集前3项最大值的方法,即运行或滚动最大值。 where itself isn't going to help. where本身没有帮助。

accumulate approximates this (this is the 'maximum' version of cumsum ) 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 is not the maximum of the previous three values, but rather the maximum of all previous values. xm不是前三个值的最大值,而是所有先前值的最大值。 In this case that's the same, but in general it won't. 在这种情况下是相同的,但一般情况下它不会。 For this x it is different for the last value 对于这个x ,最后一个值是不同的


Here's one way of getting the max of the previous 3, admittedly a bit crude (with a list comprehension): 这是获得前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)

sliding window with as_strided (adapted from Numpy: Matrix Array Shift / Insert by Index ) 带有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])

Using Paul Panzer's idea for just a few yo : 使用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)

If it is possible that yo occurs in the first 3 elements, we need to refine xm with something like: 如果有可能在前3个元素中出现yo ,我们需要使用以下内容来细化xm

xm = [max(x[max(i-3,0):i+1]) if i>0 else x[i] for i in idx[0]]

otherwise we get errors from trying to take max([]) . 否则我们会因尝试采用max([])出错。

The 'wanted' item I'm afraid you can't have because you can't have numbers in an array of string dtype. 我想你不能拥有的“通缉”项目,因为你不能在字符串dtype数组中包含数字。 where in the form you are using it 'mixes' its last two arguments into one array. where你使用它的形式中,它将最后两个参数“混合”到一个数组中。 For this it has to pick a dtype. 为此,它必须选择一个dtype。 It is going for string because of 它是为了字符串因为

>>> np.can_cast(str, int)
False
>>> np.can_cast(int, str)
True

so str is the one of the two arguments' dtypes/types that can accomodate values from both arguments. 所以str是两个参数'dtypes / types之一,可以容纳来自两个参数的值。

Data types aside you probably want to have a look at scipy.ndimage.maximum_filter : 除了数据类型之外你可能想看看scipy.ndimage.maximum_filter

>>> scipy.ndimage.maximum_filter(x, 3)
array([ 2,  8,  9,  9,  9, 12, 12, 33, 33, 33, 11,  5])

You may have to fix the offset to suit your reqirements. 您可能需要修改偏移量以满足您的要求。

Not sure I understand what you want but does this helps : 不确定我理解你想要什么,但这有助于:

x = np.sort(x)
sel = np.where(y=="yo")[0]
y[sel] = x[-len(sel):] 

?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM