gpt4 book ai didi

python - 使用 SciPy : binned_statistic + handling NaNs (ValueError with SciPy and statistic=np. nanmean 计算分箱平均值)

转载 作者:行者123 更新时间:2023-12-04 17:07:31 27 4
gpt4 key购买 nike

这个问题与这个other one有关(也许还有 this ),其中计算了分箱平均值。我尝试做同样的事情,使用 scipy-v1.5.2v1.7.3 但忽略 nan 值(如果不是,一些 binned_mean 值将返回为 nan 值;如果我替换 nan,例如,用 0s,x 轴将是正确的,但平均值不会).

这背后的原因是处理像散点图中所示的数据(包含 nan 值):

data set of interest

我的问题是,每当我计算分箱平均值(也调整分箱)时,结果主要是 nan 值,因为我的数据包含我不知道的 nan 间隔真的不想丢弃。下面是一些重现问题的代码:

from scipy.stats import binned_statistic
import numpy as np

#defining a generic data similar to mine

a=np.array([0.1, 0.15, 0.17, 0.2, 0.3, 0.4, np.nan, 0.12, 0.15, 0.17, 0.22, np.nan, 0.37, np.nan, 0.12, 0.15, 0.17, 0.17, 0.35, 0.42, np.nan])
b=np.linspace(1,len(a),len(a))
plt.scatter(b,a)
plt.hlines(np.nanmean(a),b[0],b[-1], linestyles='--')
plt.show() #you can uncomment this line to separate the plots.

#filtering nans

nana= a[~np.isnan(a)]
nanb= np.linspace(1,len(nana),len(nana))
plt.scatter(nanb,nana, marker='o')
plt.hlines(np.nanmean(a),b[0],b[-1], linestyles='--')

#calculating a binned mean
bmean_nana = binned_statistic(nanb, nana,
statistic='mean',
bins=3,
range=(0, len(nana)))

bin_centers = bmean_nana.bin_edges[1:] - (abs(bmean_nana.bin_edges[0]-bmean_nana.bin_edges[1]))/2
plt.scatter(bin_centers, bmean_nana.statistic, marker='x', s=90)

输出:

results

当分箱均值与 a 数据一起绘制时,您可以看到计算不匹配(这是有道理的)。 问题 1:是否有一个简单通用的解决方案来执行忽略 nan 值的合并均值?

一些注意事项:

  • here有一个分箱算法,它有一个 nanHandling : None 选项

‘ignore’: In this case, NaNs contained in the input data are removed from the data prior binning. Note however, that x0, unless specified explicitly, will still refer to the first data point, whether or not this holds a NaN value.

  • 还有一个 issue reported在 GitHub 中:“scipy.stats.binned_statistic 在 v1.4.0 #11365 中回归”,其中 barentsen 报告

PR #10664 recently changed the behavior of scipy.stats.binned_statistic to raise a ValueError whenever the data contains a non-finite number (e.g., nan, inf). This new behavior is counter-intuitive because many other statistical methods do not raise exceptions in the presence of NaNs, e.g. np.mean([np.nan]) returns nan rather than raising an exception.

(...) A user could choose to ignore the NaNs by providing a custom statistic function, e.g. np.nanmean:

>>> import scipy.stats, numpy as np
>>> x = [0.5, 0.5, 1.5, 1.5]
>>> values = [10, 20, np.nan, 40]
>>> scipy.stats.binned_statistic(x, values, statistic=np.nanmean, bins=(0, 1, 2)).statistic

array([15., 40.])

As of SciPy v1.4.0, the examples above raise this ValueError

>>> scipy.stats.binned_statistic(x, values, statistic=np.nanmean, bins=(0, 1, 2)).statistic
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/gb/bin/anaconda/envs/sp14/lib/python3.7/site-packages/scipy/stats/_binned_statistic.py", line 180, in binned_statistic
[x], values, statistic, bins, range)
File "/home/gb/bin/anaconda/envs/sp14/lib/python3.7/site-packages/scipy/stats/_binned_statistic.py", line 519, in binned_statistic_dd
raise ValueError('%r or %r contains non-finite values.' % (sample, values,))
ValueError: [[0.5, 0.5, 1.5, 1.5]] or [10, 20, nan, 40] contains non-finite values.

问题 2:有没有简单的方法来使用 statistic=np.nanmean

最佳答案

问题1和2的答案是使用np.nanmean忽略数据中的nan。您链接到的回归是我无意中引入的错误,然后在提出后修复。我不确定为什么您的环境中有 SciPy 1.5.2,it looks like 1.5.4 是最新的 1.5.X 版本,所以您可能想要更新您正在使用的环境。然而,那个backport已应用于版本 1.5.0 发布版本,因此如果您拥有最新版本,这些版本应该不会有问题。

此外,我使用 scipy 版本 1.7.3 进行了设置,它也适用于我。以下是片段。

版本 1.5.4

import scipy
scipy.__version__
'1.5.4'
import numpy as np
x = [0.5, 0.5, 1.5, 1.5]
values = [10, 20, np.nan, 40]
scipy.stats.binned_statistic(x, values, statistic='mean', bins=(0, 1, 2)).statistic
array([15., nan])
scipy.stats.binned_statistic(x, values, statistic=np.nanmean, bins=(0, 1, 2)).statistic
array([15., 40.])

版本 1.7.3

import scipy
scipy.__version__
'1.7.3'
import scipy.stats, numpy as np
x = [0.5, 0.5, 1.5, 1.5]
values = [10, 20, np.nan, 40]
scipy.stats.binned_statistic(x, values, statistic='mean', bins=(0, 1, 2)).statistic
array([15., nan])
scipy.stats.binned_statistic(x, values, statistic=np.nanmean, bins=(0, 1, 2)).statistic
array([15., 40.])

版本 1.5.2

import scipy
scipy.__version__
'1.5.2'
import scipy.stats, numpy as np
x = [0.5, 0.5, 1.5, 1.5]
values = [10, 20, np.nan, 40]
scipy.stats.binned_statistic(x, values, statistic='mean', bins=(0, 1, 2)).statistic
array([15., nan])
scipy.stats.binned_statistic(x, values, statistic=np.nanmean, bins=(0, 1, 2)).statistic
array([15., 40.])

请尝试使用 .__version__ 来确认您的 SciPy 版本。如果它是 1.4.1 版本-它没有变化。我怀疑您的版本是 1.4.1 而不是其他(更高)版本。请使用上面的代码示例部分来确认您的环境中使用的 scipy 版本。

关于python - 使用 SciPy : binned_statistic + handling NaNs (ValueError with SciPy and statistic=np. nanmean 计算分箱平均值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70249711/

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