【问题标题】:scipy stats error in calculating standard normal in python在python中计算标准法线时scipy stats错误
【发布时间】:2018-02-01 08:26:25
【问题描述】:

我试图在 python 中为我的数据df 计算正态分布下的概率。我对python或编程没有经验。我从本网站抓取的以下用户定义函数有效,scipy 函数无效...

UDF:

def normal(x,mu,sigma):
    return ( 2.*np.pi*sigma**2. )**-.5 * np.exp( -.5 * (x-mu)**2. / sigma**2. )
df["normprob"] = normal(df["return"],df["meanreturn"],df["sdreturn"])

这个 scipy 函数不起作用:

df["normdistprob"] = scip.norm.sf(df["return"],df["meanreturn"],df["sdreturn"])

它会返回以下错误

C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1815: RuntimeWarning: invalid value encountered in true_divide
  x = np.asarray((x - loc)/scale, dtype=dtyp)
C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1816: RuntimeWarning: invalid value encountered in greater
  cond0 = self._argcheck(*args) & (scale > 0)
C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:879: RuntimeWarning: invalid value encountered in greater
  return (self.a < x) & (x < self.b)
C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:879: RuntimeWarning: invalid value encountered in less
  return (self.a < x) & (x < self.b)
C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1817: RuntimeWarning: invalid value encountered in greater
  cond1 = self._open_support_mask(x) & (scale > 0)
C:\Anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1818: RuntimeWarning: invalid value encountered in less_equal
  cond2 = cond0 & (x <= self.a)

感谢任何建议。还要注意,前 20 个单元格的

df["meanreturn"]

不适用,不确定是否会影响它。

【问题讨论】:

  • 是的,在任何数学计算中使用 NA 都会使其崩溃
  • 如果平均值为 NA,您计算概率的预期方法是什么?
  • 好吧,我想即使它是前 20 个单元格,也不会影响数据集的其余部分,并且 'df["normdist"]' 的前 20 个单元格只是 NaN以及。另外,从这个链接stackoverflow.com/questions/25039328/…,似乎 NaN 单元格无关紧要?

标签: python numpy scipy


【解决方案1】:

不确定生存功能是否是您所需要的。我相信您正在寻找的是 scipy 的 pdf 函数,特别是普通随机变量的 pdf。我根据您使用的自定义函数对其进行了测试。

>>> from scipy.stats import norm
>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'x': [0.6, 0.5, 0.13], 'mu': [0, 1, 1], 'std': [1, 2, 1]})
>>> norm.pdf(df['x'], df['mu'], df['std'])
array([ 0.3332246 ,  0.19333406,  0.27324443])
>>> def normal(x,mu,sigma):
...     return ( 2.*np.pi*sigma**2. )**-.5 * np.exp( -.5 * (x-mu)**2. / sigma**2. )
...
>>> normal(df['x'], df['mu'], df['std'])
0    0.333225
1    0.193334
2    0.273244
dtype: float64

请注意,如果您的 mustd 列是 np.nan,那么您将收到运行时警告,但您仍会收到输出,类似于自定义函数。

>>> df = pd.DataFrame({'x': [0.6, 0.5, 0.13], 'mu': [np.nan, 1, 1], 'std': [np.nan, 2, np.nan]})
>>> norm.pdf(df['x'], df['mu'], df['std'])
C:\Users\lyang3\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1650: RuntimeWarning: invalid value encountered in greater
  cond0 = self._argcheck(*args) & (scale > 0)
C:\Users\lyang3\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:876: RuntimeWarning: invalid value encountered in greater_equal
  return (self.a <= x) & (x <= self.b)
C:\Users\lyang3\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:876: RuntimeWarning: invalid value encountered in less_equal
  return (self.a <= x) & (x <= self.b)
C:\Users\lyang3\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\stats\_distn_infrastructure.py:1651: RuntimeWarning: invalid value encountered in greater
  cond1 = self._support_mask(x) & (scale > 0)
array([        nan,  0.19333406,         nan])
>>> normal(df['x'], df['mu'], df['std'])
0         NaN
1    0.193334
2         NaN
dtype: float64

如果将 np.nan 值设置为 None,则可以避免警告:

>>> df = pd.DataFrame({'x': [0.6, 0.5, 0.13], 'mu': [None, 1, 1], 'std': [None, 2, None]})
>>> normal(df['x'], df['mu'], df['std'])
0         NaN
1    0.193334
2         NaN
dtype: float64
>>> norm.pdf(df['x'], df['mu'], df['std'])
array([        nan,  0.19333406,         nan])

注意,我会删除 meanreturnsdreturn 值为 NaN 的行。否则,我会假设您正在寻找 x 假设标准正态分布的概率,然后您必须将 meanreturnNaN 值设置为 0 和 @987654337 的 NaN 值@ 到 1。

要添加的最后一条评论是,如果数据框的所有行都采用标准正态分布来计算 pdf 的概率,那么您不需要传递 mu 列和 std 列。 norm.pdf 已经假定为标准法线。在这种情况下,您可以像这样运行代码:

>>> norm.pdf(df['x'])
array([ 0.3332246 ,  0.35206533,  0.39558542])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-29
    • 2012-08-12
    • 2022-11-01
    • 1970-01-01
    • 2021-09-12
    • 2016-03-12
    • 2017-10-03
    • 2021-12-27
    相关资源
    最近更新 更多