Python numpy数组中无for循环的迭代
我需要对numpy数组进行逻辑迭代,它的值取决于其他数组的元素。我已经写了下面的代码来澄清我的问题。在没有for循环的情况下解决这个问题有什么建议吗Python numpy数组中无for循环的迭代,python,numpy,iterator,vectorization,Python,Numpy,Iterator,Vectorization,我需要对numpy数组进行逻辑迭代,它的值取决于其他数组的元素。我已经写了下面的代码来澄清我的问题。在没有for循环的情况下解决这个问题有什么建议吗 Code a = np.array(['a', 'b', 'a', 'a', 'b', 'a']) b = np.array([150, 154, 147, 126, 148, 125]) c = np.zeros_like(b) c[0] = 150 for i in range(1, c.size): if a[i] == "b":
Code
a = np.array(['a', 'b', 'a', 'a', 'b', 'a'])
b = np.array([150, 154, 147, 126, 148, 125])
c = np.zeros_like(b)
c[0] = 150
for i in range(1, c.size):
if a[i] == "b":
c[i] = c[i-1]
else:
c[i] = b[i]
这里有一种方法,使用和的组合来创建以一定间隔停止的分级索引,然后简单地索引到
b
中,就可以得到所需的输出
因此,将需要实施-
mask = a!="b"
idx = np.maximum.accumulate(np.where(mask,np.arange(mask.size),0))
out = b[idx]
分步运行示例-
In [656]: # Inputs
...: a = np.array(['a', 'b', 'a', 'a', 'b', 'a'])
...: b = np.array([150, 154, 147, 126, 148, 125])
...:
In [657]: mask = a!="b"
In [658]: mask
Out[658]: array([ True, False, True, True, False, True], dtype=bool)
# Crux of the implmentation happens here :
In [696]: np.where(mask,np.arange(mask.size),0)
Out[696]: array([0, 0, 2, 3, 0, 5])
In [697]: np.maximum.accumulate(np.where(mask,np.arange(mask.size),0))
Out[697]: array([0, 0, 2, 3, 3, 5])# Stepped indices "intervaled" at masked places
In [698]: idx = np.maximum.accumulate(np.where(mask,np.arange(mask.size),0))
In [699]: b[idx]
Out[699]: array([150, 150, 147, 126, 126, 125])
您可以使用更矢量化的方法,如下所示:
np.where(a == "b", np.roll(c, 1), b)
np.where
将从np.roll(c,1)
中获取元素,如果条件为True
,则从b
中获取元素,如果条件为False
<代码>np。滚动(c,1)将c
的所有元素向前滚动1,以便每个元素都指向c[i-1]
这些类型的操作使得numpy如此无价。如果可能的话,应该避免循环。如果您不需要环绕边距,有一个非常简单的解决方案:
a = np.array(['a', 'b', 'a', 'a', 'b', 'a'])
b = np.array([150, 154, 147, 126, 148, 125])
c = b.copy() #removes necessity of else case
c[a[:-1]=='b'] = c[a[1:]=='b']
或者同等地:
a = np.array(['a', 'b', 'a', 'a', 'b', 'a'])
b = np.array([150, 154, 147, 126, 148, 125])
c = b.copy() #removes necessity of else case
mask = a == 'b'
c[mask[:-1]] = c[mask[1:]]
如果你想围绕页边(
a[0]==“b”
),那么它会变得更复杂一些,你要么需要使用roll
,要么先用和If
抓住这个例子,这是一个简单而简洁的解决方案。但是,为什么它会返回[150 0 147 126 0 125]?它不从a[i]=“b”的“b”数组中获取值。我误解了这个问题,只有当你已经拥有了c
的所有元素时,这才有效,但是你通过循环填充它,所以它比这个稍微复杂一点