gpt4 book ai didi

python - 对 python 元组进行分箱。由于空箱而导致错误

转载 作者:太空宇宙 更新时间:2023-11-03 18:37:40 24 4
gpt4 key购买 nike

我在将列表项排序到垃圾箱时遇到问题。我有两个列表,X 和 Y,以及相应的 X 和 Y 值(显然,这也可以是一个元组列表)。接下来,我需要将 X 范围分成 10 个相等的 bin,并对这些 bin 的 X 值和相应的 Y 值进行排序,以便我知道哪些 Y 值属于哪个 X bin(即每个 Y 的 X 值属于哪个 bin)值),然后取每个 bin 中所有 Y 值的中位数。这给了我十个 bin-median 对。原则上,使用以下代码可以正常工作,其中我还计算了每个 bin 的 X 中心。

    bins = np.linspace(max(X), min(X), 10)
digitized = np.digitize(X, bins)
bin_centers = []
for j in range(len(bins) - 1):
bin_centers.append((bins[j] + bins[j + 1]) / 2.)
bin_means = [np.median(np.asarray(Y)[digitized == j])
for j in range(1, len(bins))]

现在的问题是,有时某个 bin 是空的,因为该 bin 中没有 X 值。在这种情况下,该行

    bin_means = [np.median(np.asarray(Y)[digitized == j])
for j in range(1, len(bins))]

引发错误

/usr/lib64/python2.6/site-packages/numpy/core/_methods.py:55: RuntimeWarning: Mean of empty slice.
FloatingPointError: invalid value encountered in double_scalars

因为垃圾箱是空的。我该如何解决这个问题?我还在 numpy.digitize 中尝试过 right=True/False 但没有成功。我认为最好在执行此列表理解(计算中值。但我不知道该怎么做,如何找出哪些垃圾箱是空的,然后必须从这些列表中删除哪些内容以及如何删除。有任何想法吗?谢谢!

最佳答案

如果你有Scipy,你可以调用scipy.stats.binned_statistic :

import scipy.stats as stats
statistic, bin_edges, binnumber = stats.binned_statistic(
x=X, values=Y, statistic='median', bins=bins)
statistic = statistic[np.isfinite(statistic)]
print(statistic)

产量

[ 15.  90.  50.  55.  40.  60.]
<小时/>

如果没有 SciPy,我认为您需要列表理解。正如您所建议的,您可以通过过滤掉那些空的垃圾箱来避免运行时警告。您可以使用列表理解中的 if-condition 来做到这一点:

masks = [(digitized == j) for j in range(1, len(bins))]
bin_medians = [np.median(Y[mask]) for mask in masks if mask.any()]

另请注意,您看到的错误消息是警告,而不是异常。您可以(或者)使用

抑制错误消息
import warnings
warnings.filterwarnings("ignore", 'Mean of empty slice.')
warnings.filterwarnings("ignore", 'invalid value encountered in double_scalar')
<小时/>

有一种方法可以更快地计算 bin_centers:

bin_centers = []
for j in range(len(bins) - 1):
bin_centers.append((bins[j] + bins[j + 1]) / 2.)

可以简化为

bin_centers = bins[:-1] + (bins[1]-bins[0])/2
<小时/>

例如,

import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore", 'Mean of empty slice.')
warnings.filterwarnings("ignore", 'invalid value encountered in double_scalar')

np.random.seed(123)

X = np.random.random(10)
bins = np.linspace(min(X), max(X), 10)
digitized = np.digitize(X, bins)-1
bin_centers = bins + (bins[1]-bins[0])/2

Y = range(0, 100, 10)
Y = np.asarray(Y, dtype='float')
bin_medians = [np.median(Y[digitized == j]) for j in range(len(bins))]
print(bin_medians)

plt.scatter(bin_centers, bin_medians)
plt.show()

产量

[15.0, 90.0, 50.0, 55.0, nan, 40.0, nan, nan, nan, 60.0]

enter image description here

如果您的目的只是制作散点图,则无需删除 nan,因为 matplotlib 无论如何都会忽略它们。

如果你真的想删除nans,那么你可以使用

no_nans = np.isfinite(bin_medians)
bin_medians = bin_medians[no_nans]
bin_centers = bin_centers[no_nans]
<小时/>

在上面,我选择使用 warnings.filterwarnings 来抑制警告。如果您不想抑制警告,而是希望从 bin_mediansbin_centers 的相应位置过滤 nan,则:

bin_centers = bins + (bins[1]-bins[0])/2
masks = [(digitized == j) for j in range(len(bins))]
bin_centers, bin_medians = zip(*[(center, np.median(Y[mask]))
for center, mask in zip(bin_centers, masks)
if mask.any()])

关于python - 对 python 元组进行分箱。由于空箱而导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21241624/

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