循环中的数组
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
当 k
为 len(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 边缘。它与 X
或 Y
数组的大小不同。
当您 zip
将序列放在一起时,zip
在迭代最短序列时停止。例如:
for i, j in zip([1, 2], [5, 6, 7, 8, 9]):
print j
将产生:
5
6
在您的情况下,您实际上想要遍历 bin,然后在 X
和 Y
上进行内部循环。例如:
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]
无论哪种方式,为此使用布尔索引而不是内部循环都会产生显着的加速。
您好,我有一个问题,我不确定如何在 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
当 k
为 len(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 边缘。它与 X
或 Y
数组的大小不同。
当您 zip
将序列放在一起时,zip
在迭代最短序列时停止。例如:
for i, j in zip([1, 2], [5, 6, 7, 8, 9]):
print j
将产生:
5
6
在您的情况下,您实际上想要遍历 bin,然后在 X
和 Y
上进行内部循环。例如:
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]
无论哪种方式,为此使用布尔索引而不是内部循环都会产生显着的加速。