pythonic方法用超出邻居值的限制替换数组中的值

时间:2022-03-29 01:30:52

I'm replacing values in an array above a limit like so:

我正在将数组中的值替换为限制,如下所示:

ys[ys > zmax] = zmin

But now instead of replacing values that are larger than zmax with zmin, I want to replace them with the value of the neighbour in the array that is preceding them: if ys[30] is > zmax, I want to assign the previous value:

但是现在不是用zmin替换大于zmax的值,而是想用它们之前的数组中的邻居值替换它们:如果ys [30]是> zmax,我想分配前一个值:

ys[30] = ys[29]

But since the pythonic way doesn't deal with simple things like indices, I have no clue how to do that. Anyone?

但由于pythonic方式不处理像索引这样的简单事物,我不知道如何做到这一点。任何人?

3 个解决方案

#1


3  

I think this is what you're asking for:

我想这就是你要求的:

>>> l = [5, 10, 25, 33, 6, 8, 19]
>>> zmax = 15
>>> [l[idx-1] if (ent > zmax) and (idx > 0) else ent for idx, ent in enumerate(l)]
[5, 10, 10, 25, 6, 8, 8]

We just use enumerate to get both the index and value for each item in the list, and if the value is greater than zmax, replace it with l[index-1], otherwise we just take the original value. I'm not sure how you want the case where l[0] > zmax to be handled, so I'm just not replacing it at all for now.

我们只使用枚举来获取列表中每个项的索引和值,如果值大于zmax,则将其替换为l [index-1],否则我们只取原始值。我不确定你想要处理l [0]> zmax的情况,所以我现在根本不更换它。

Here's the same logic as a normal for loop, just for clarify:

这是与正常for循环相同的逻辑,只是为了澄清:

new_l = [] for idx, ent in enumerate(l): if (ent > zmax) and (idx > 0): cnt = idx -1 while l[cnt] > zmax: cnt -=1 new_l.append(l[cnt]) else: new_l.append(ent)

new_l = [] for idx,ent in enumerate(l):if(ent> zmax)and(idx> 0):cnt = idx -1而l [cnt]> zmax:cnt - = 1 new_l.append(l [ cnt])else:new_l.append(ent)

Edit

编辑

Here's a simple way to attempt to make sure none of the values in the new list are higher than zmax, by trying to swap with the closest, smaller index in the list that contains a value less than zmax. Again, if no lower index has a value smaller than zmax, we do nothing.

这是一种尝试通过尝试与包含小于zmax的值的列表中最接近的较小索引进行交换来尝试确保新列表中的值都不高于zmax的简单方法。同样,如果没有较低的索引值小于zmax,我们什么都不做。

new_l = []
for idx, ent in enumerate(l):
   if (ent > zmax) and (idx > 0):
      cnt = idx - 1
      while l[cnt] > zmax and cnt > 0:
          cnt -= 1
      new_val = l[cnt] if l[cnt] <= zmax else l[idx] # If we didn't find a good index to swap with, keep the original
      new_l.append(new_val)
   else:
      new_l.append(ent)

#2


2  

Okay, how about this:

好的,这个怎么样:

>>> ys = np.array([10,15,20,30,14,20,30,15,20])
>>> zmax = 15
>>> ys
array([10, 15, 20, 30, 14, 20, 30, 15, 20])
>>> ys[np.maximum.accumulate(np.arange(len(ys)) * (ys <= zmax))]
array([10, 15, 15, 15, 14, 14, 14, 15, 15])

This produces a forward fill by taking the indices we'd ordinarily use:

这通过获取我们通常使用的指数产生前向填充:

>>> np.arange(len(ys))
array([0, 1, 2, 3, 4, 5, 6, 7, 8])

Finding the ones we want to keep:

找到我们想要保留的:

>>> ys <= zmax
array([ True,  True, False, False,  True, False, False,  True, False], dtype=bool)

Zeroing the indices that we don't want to keep:

归零我们不想保留的指数:

>>> np.arange(len(ys)) * (ys <= zmax)
array([0, 1, 0, 0, 4, 0, 0, 7, 0])

and then taking the cumulative maximum:

然后取累积最大值:

>>> np.maximum.accumulate(np.arange(len(ys)) * (ys <= zmax))
array([0, 1, 1, 1, 4, 4, 4, 7, 7])

#3


2  

Here it is in pure python assuming that your first index is less than the max. If you don't want to use numpy - although numpy is probably very fast

假设你的第一个索引小于最大值,那么它就是纯python。如果你不想使用numpy - 虽然numpy可能非常快

ys = [int(uniform(1, 10)) for i in range(20)]
print ys, "before"

maxVal = 5 #set max
for i in range(1, len(ys)):
    if ys[i] > maxVal:
        ys[i] = ys[i-1]

print ys, "after"

output

产量

[3, 8, 9, 8, 9, 8, 7, 3, 4, 9, 1, 4, 4, 2, 2, 1, 4, 5, 3, 6] before
[3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 1, 4, 4, 2, 2, 1, 4, 5, 3, 3] after

#1


3  

I think this is what you're asking for:

我想这就是你要求的:

>>> l = [5, 10, 25, 33, 6, 8, 19]
>>> zmax = 15
>>> [l[idx-1] if (ent > zmax) and (idx > 0) else ent for idx, ent in enumerate(l)]
[5, 10, 10, 25, 6, 8, 8]

We just use enumerate to get both the index and value for each item in the list, and if the value is greater than zmax, replace it with l[index-1], otherwise we just take the original value. I'm not sure how you want the case where l[0] > zmax to be handled, so I'm just not replacing it at all for now.

我们只使用枚举来获取列表中每个项的索引和值,如果值大于zmax,则将其替换为l [index-1],否则我们只取原始值。我不确定你想要处理l [0]> zmax的情况,所以我现在根本不更换它。

Here's the same logic as a normal for loop, just for clarify:

这是与正常for循环相同的逻辑,只是为了澄清:

new_l = [] for idx, ent in enumerate(l): if (ent > zmax) and (idx > 0): cnt = idx -1 while l[cnt] > zmax: cnt -=1 new_l.append(l[cnt]) else: new_l.append(ent)

new_l = [] for idx,ent in enumerate(l):if(ent> zmax)and(idx> 0):cnt = idx -1而l [cnt]> zmax:cnt - = 1 new_l.append(l [ cnt])else:new_l.append(ent)

Edit

编辑

Here's a simple way to attempt to make sure none of the values in the new list are higher than zmax, by trying to swap with the closest, smaller index in the list that contains a value less than zmax. Again, if no lower index has a value smaller than zmax, we do nothing.

这是一种尝试通过尝试与包含小于zmax的值的列表中最接近的较小索引进行交换来尝试确保新列表中的值都不高于zmax的简单方法。同样,如果没有较低的索引值小于zmax,我们什么都不做。

new_l = []
for idx, ent in enumerate(l):
   if (ent > zmax) and (idx > 0):
      cnt = idx - 1
      while l[cnt] > zmax and cnt > 0:
          cnt -= 1
      new_val = l[cnt] if l[cnt] <= zmax else l[idx] # If we didn't find a good index to swap with, keep the original
      new_l.append(new_val)
   else:
      new_l.append(ent)

#2


2  

Okay, how about this:

好的,这个怎么样:

>>> ys = np.array([10,15,20,30,14,20,30,15,20])
>>> zmax = 15
>>> ys
array([10, 15, 20, 30, 14, 20, 30, 15, 20])
>>> ys[np.maximum.accumulate(np.arange(len(ys)) * (ys <= zmax))]
array([10, 15, 15, 15, 14, 14, 14, 15, 15])

This produces a forward fill by taking the indices we'd ordinarily use:

这通过获取我们通常使用的指数产生前向填充:

>>> np.arange(len(ys))
array([0, 1, 2, 3, 4, 5, 6, 7, 8])

Finding the ones we want to keep:

找到我们想要保留的:

>>> ys <= zmax
array([ True,  True, False, False,  True, False, False,  True, False], dtype=bool)

Zeroing the indices that we don't want to keep:

归零我们不想保留的指数:

>>> np.arange(len(ys)) * (ys <= zmax)
array([0, 1, 0, 0, 4, 0, 0, 7, 0])

and then taking the cumulative maximum:

然后取累积最大值:

>>> np.maximum.accumulate(np.arange(len(ys)) * (ys <= zmax))
array([0, 1, 1, 1, 4, 4, 4, 7, 7])

#3


2  

Here it is in pure python assuming that your first index is less than the max. If you don't want to use numpy - although numpy is probably very fast

假设你的第一个索引小于最大值,那么它就是纯python。如果你不想使用numpy - 虽然numpy可能非常快

ys = [int(uniform(1, 10)) for i in range(20)]
print ys, "before"

maxVal = 5 #set max
for i in range(1, len(ys)):
    if ys[i] > maxVal:
        ys[i] = ys[i-1]

print ys, "after"

output

产量

[3, 8, 9, 8, 9, 8, 7, 3, 4, 9, 1, 4, 4, 2, 2, 1, 4, 5, 3, 6] before
[3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 1, 4, 4, 2, 2, 1, 4, 5, 3, 3] after