numpy Python -替换数组中1之前的值

gev0vcfq  于 2023-01-20  发布在  Python
关注(0)|答案(5)|浏览(133)

假设我有一个由0和1组成的Pandas系列,但这可以用于numpy数组或任何可迭代对象。我想创建一个公式,它接受一个数组和一个输入n,然后返回一个新的系列,该系列在第n个索引处包含1,直到每次原始系列中至少有一个1。下面是一个示例:

array = np.array([0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1])

> preceding_indices_function(array, 2)
np.array([0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1])

每当输入数组中有1时,它前面的两个索引都用1填充,而不管原始数组中的该索引是0还是1。
我真的很感激你的帮助。谢谢!

vc9ivgsu

vc9ivgsu1#

np.convolve使用卷积:

N = 2

# craft a custom kernel
kernel = np.ones(2*N+1)
kernel[-N:] = 0
# array([1, 1, 1, 0, 0])

out = (np.convolve(array, kernel, mode='same') != 0).astype(int)

输出:

array([0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1])
6kkfgxo0

6kkfgxo02#

除非你不想使用numpy,mozway的transpose是最好的解决方案。
但是由于已经给出了几次迭代,我添加了基于itertools的解决方案

[a or b or c for a,b,c in itertools.zip_longest(array, array[1:], array[2:], fillvalue=0)]

zip_longest与经典的zip相同,但如果迭代器有不同的“长度”,则迭代次数是最长的一个,完成的迭代器将返回None。除非您在zip_longest中添加了一个fillvalue参数。
因此,这里itertools.zip_longest(array, array[1:], array[2:], fillvalue=0)给出了一个三元组(a,B,c)的序列,具有3个后续元素(a是当前元素,b是下一个,c是后一个,如果没有任何下一个元素或下一个之后的元素,则b和c为0)。
因此,从那里,一个简单的理解建立一个[a or b or c]的列表,如果a,b或c是1,则为1,否则为0。

lrl1mhuk

lrl1mhuk3#

import numpy as np

array = np.array([0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1])

array = np.array([a or array[idx+1] or array[idx+2] for idx, a in enumerate(array[:-2])] + [array[-2] or array[-1]] + [array[-1]])
r6l8ljro

r6l8ljro4#

如果a是一个列表,这个函数就可以工作,应该也可以和其他迭代对象一起工作:

def preceding_indices_function(array, n):
  for i in range(len(a)):
    if array[i] == 1:
      for j in range(n):
        if i-j-1 >= 0:
          array[i-j-1] = 1
  return array
sqyvllje

sqyvllje5#

我得到了一个与另一个类似但在我看来稍微简单一些的解决方案:

>>> [1 if (array[i+1] == 1 or array[i+2] == 1) else x for i,x in enumerate(array) if i < len(array) - 2]
[0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]

相关问题