gpt4 book ai didi

python - 将操作应用于 numpy 数组的不均匀分割部分

转载 作者:太空宇宙 更新时间:2023-11-04 02:55:48 26 4
gpt4 key购买 nike

我有三个一维 numpy 数组:

  1. 一些测量发生的时间列表 ( t )。
  2. t 中的每个时间发生的测量列表(y)。
  3. 影响这些测量的一些外部变化的(较短的)时间列表 (b)。

这是一个例子:

t = np.array([0.33856697,   1.69615293,   1.70257872,   2.32510279,              2.37788203,   2.45102176,   2.87518307,   3.60941650,              3.78275907,   4.37970516,   4.56480259,   5.33306546,              6.00867792,   7.40217571,   7.46716989,   7.6791613 ,              7.96938078,   8.41620336,   9.17116349,  10.87530965])y = np.array([ 3.70209916,  6.31148802,  2.96578172,  3.90036915, 5.11728629,               2.85788050,  4.50077811,  4.05113322,  3.55551093, 7.58624384,               5.47249362,  5.00286872,  6.26664832,  7.08640263, 5.28350628,               7.71646500,  3.75513591,  5.72849991,  5.60717179, 3.99436659])b = np.array([ 1.7,  3.9,  9.5])

The elements of b fall between the bold and italicized elements t, breaking it into four uneven sized segments of lengths 2, 7, 10, 1.

I would like to apply an operation to each segment of y to get an array of size b.size + 1. Specifically, I want to know if more than half of the values of y within each segment fall above or below a certain bias.

I am currently using a for loop and slicing to apply my test:

bias = 5
categories = np.digitize(t, b)
result = np.empty(b.size + 1, dtype=np.bool_)
for i in range(result.size):
mask = (categories == i)
result[i] = (np.count_nonzero(y[mask] > bias) / np.count_nonzero(mask)) > 0.5

这看起来效率极低。不幸的是,np.where在这种情况下不会有太大帮助。有没有一种方法可以对我在此处描述的操作进行矢量化以避免 Python for循环?


顺便说一句,这是y的情节对比t , bias , 以及由 b 分隔的区域显示为什么预期 resultarray([False, False, True, False], dtype=bool) :

enter image description here

生成者

from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
plt.ion()
f, a = plt.subplots()
a.plot(t, y, label='y vs t')
a.hlines(5, *a.get_xlim(), label='bias')
plt.tight_layout()
a.set_xlim(0, 11)
c = np.concatenate([[0], b, [11]])
for i in range(len(c) - 1):
a.add_patch(Rectangle((c[i], 2.5), c[i+1] - c[i], 8 - 2.5, alpha=0.2, color=('red' if i % 2 else 'green'), zorder=-i-5))
a.legend()

最佳答案

这不应该产生相同的结果吗?

split_points = np.searchsorted(t, np.r_[t[0], b, t[-1]])
numerator = np.add.reduceat(y > bias, split_points[:-1])
denominator = np.diff(split_points)
result = (numerator / denominator) > 0.5

注意事项:此方法依赖于对 t 进行排序。那么与 b 相关的 bins 都将是整齐的 block ,因此我们不需要掩码来描述它们,而只需要 t 中索引形式的端点。这就是searchsorted为我们找到。

由于您的标准似乎不依赖于组,我们可以一次性为所有 y 制作一个大面具。计算 bool 数组中的非零值与求和相同,因为 True 将被强制转换为 1 等。这种情况的优点是我们可以使用 add.reduceat。它采用数组、拆分点列表,然后对拆分之间的 block 求和,这正是我们想要的。

为了规范化,我们需要计算每个箱子中的总数,但因为箱子是连续的,我们只需要描绘那个箱子的 split_points 的差异,这就是我们使用 diff 的地方。 .

关于python - 将操作应用于 numpy 数组的不均匀分割部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42447497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com