循环中的数组

Arrays in loops

您好,我有一个问题,我不确定如何在 python 中实施。 我有三个不同的数组。我在 X 中有值,在 Y 中有值。这样每个 X 都有一个特定的 Y 属于 (X,Y)。现在,我从中构建了一个直方图。

U, V = histogram(X, bins=arange(min(X), max(X), 50))

第三个数组 (V) 包含每个 bin 的点数。知道这一点后,我想为不同容器中的每个点打印不同的 Y 值。它是:

for i, j in zip(X, Y):
     if a<i<b:
         print j

其中 a 是 V 中的第一个值,b 是第二个值。例如在我的第一种情况下,第一个值是 500,第二个值是 600,所以它将是:

for i, j in zip(X, Y):
     if 500<i<600:
         print j

这里它打印 X 中 500-600 范围内的点的 Y 值。现在我想做的是实现一个循环,这样我就不必手动编写不同的V 的条目。我在想类似的事情:

for i, j, k in zip(X,Y,range(len(V))):
     if V[k]<i<V[k+1]:
         print j 

但是没用。有什么想法吗?

您遇到的错误是什么?您可能在

中的数组之外进行索引
for i, j, k in zip(X,Y,range(len(V))):
     if V[k]<i<V[k+1]:
         print j 

klen(V) 时,没有 V[k+1]。你可以这样做

for i, j, k in zip(X,Y,range(len(V)-1)):
     if V[k]<i<V[k+1]:
         print j 
#handle the last bin separately
if X[-1] > V[-1]:
    print Y[-1]

从你问题中的代码来看,你似乎在使用 numpy。在 numpy 中有更好的方法来解决这个问题,我将在答案的最后讨论这些方法。不过,现在让我们看看为什么您尝试的方法不起作用。


它不起作用的原因是您的 V 数组是 bin 边缘。它与 XY 数组的大小不同。

当您 zip 将序列放在一起时,zip 在迭代最短序列时停止。例如:

for i, j in zip([1, 2], [5, 6, 7, 8, 9]):
    print j

将产生:

5
6

在您的情况下,您实际上想要遍历 bin,然后在 XY 上进行内部循环。例如:

for k in range(len(V)):
     for i, j in zip(x, y):
         if V[k]<i<V[k+1]:
             print j 

我们还可以通过以下方式使它更具可读性:

bin_edges = V

for left, right in zip(bin_edges, bin_edges[1:]):
    for i, j in zip(x, y):
        if left < i < right:
            print j

然而,这两者在 numpy 中可怕 低效。 (遍历 numpy 数组比遍历列表慢,但即使使用列表也会很慢。)

幸运的是,您使用的是 numpy,还有 很多 更有效的方法。


首先,让我们重现上面的示例,但是让我们使用布尔索引来删除内部循环:

import numpy as np

# Generate some random data
x, y = np.random.random((2, 100))

# Your "U" and "V" arrays, but I'm changing the names for clarity
counts, bins = np.histogram(x, bins=20)

# Rather than iterate over an index, let's use a slightly different trick
for left, right in zip(bins[:-1], bins[1:]):
    # Use boolean indexing to replace the inner loop
    print y[(x > left) & (x < right)]

另一种方法是通过 numpy.digitize:

import numpy as np

# Generate some x, y data
x, y = np.random(2, 100)

# Create a histogram of x
counts, bins = np.histogram(x, bins=30)

# Return an series of indicies of which bin each x-value falls into
# This will be the same size as x and have values between 0 to len(bins)
idx = np.digitize(x, bins)

# Print the y-values for each bin
for i in range(bins.size):
   y[idx == i]

无论哪种方式,为此使用布尔索引而不是内部循环都会产生显着的加速。