【问题标题】:Why am I getting 0 for Series.prod()?为什么我的 Series.prod() 为 0?
【发布时间】:2013-09-02 00:17:50
【问题描述】:

我有一个由正数或 nan 组成的系列。但是当我计算产品时,我得到 0。

样本输出:

    In [14]: pricerelatives.mean()
    Out[14]: 0.99110019490541013
    In [15]: pricerelatives.prod()
    Out[15]: 0.0
    In [16]: len(pricerelatives)
    Out[16]: 362698
    In [17]: (pricerelatives>0).sum()
    Out[17]: 223522
    In [18]: (pricerelatives.isnull()).sum()
    Out[18]: 139176
    In [19]: 223522+139176
    Out[19]: 362698

为什么pricerelatives.prod() 得到 0?

更新: 感谢您及时的回复。不幸的是,它不起作用:

    In [32]: import operator
    In [33]: from functools import reduce
    In [34]: lst = list(pricerelatives.fillna(1))
    In [35]: the_prod = reduce(operator.mul, lst)
    In [36]: the_prod
    Out[36]: 0.0

明确去除空值也失败了:

    In [37]: pricerelatives[pricerelatives.notnull()].prod()
    Out[37]: 0.0

更新 2: 确实,这正是我刚刚做的并将添加的内容。

    In [39]: pricerelatives.describe()
    Out[39]: 
    count    223522.000000
    mean          0.991100
    std           0.088478
    min           0.116398
    25%           1.000000
    50%           1.000000
    75%           1.000000
    max          11.062591
    dtype: float64

更新 3:对我来说仍然很奇怪。所以更详细的信息:

    In [46]: pricerelatives[pricerelatives<1].describe()
    Out[46]: 
    count    50160.000000
    mean         0.922993
    std          0.083865
    min          0.116398
    25%          0.894997
    50%          0.951488
    75%          0.982058
    max          1.000000
    dtype: float64

更新 4:该比率正好在您示例的 0 和 >0 之间的截止值附近,但我的数字比统一的 0,1 和统一的 1,2 更集中在 1 附近。

    In [52]: 50160./223522
    Out[52]: 0.2244074408783028
    In [53]: pricerelatives[pricerelatives>=1].describe()
    Out[53]: 
    count    173362.000000
    mean          1.010806
    std           0.079548
    min           1.000000
    25%           1.000000
    50%           1.000000
    75%           1.000000
    max          11.062591
    dtype: float64
    In [54]: pricerelatives[pricerelatives<1].prod()
    Out[54]: 0.0

【问题讨论】:

  • 你能显示pricerelatives.describe()吗?
  • 您能否在更新 3 中显示 &gt;=1 而不是 &gt;1
  • 另外,计算值
  • 为什么更新 4 中的第 54 行没有回答您的问题?
  • 我想是的。非常感谢!顺便说一句,我找到了一种计算方法。我正在计算产品,以便获得几何平均值。与其先拿产品,不如先做**1/n解决问题。

标签: numpy pandas precision multiplication series


【解决方案1】:

这看起来像是numpy 中的“错误”;见here。溢出时不会升起。

这里有一些例子:

In [26]: prod(poisson(10, size=30))
Out[26]: -2043494819862020096

In [46]: prod(randn(10000))
Out[46]: 0.0

您必须使用 long (Python 2) 或 int (Python 3) 类型并使用 reduce/functools.reduce 减少它:

import operator
from functools import reduce

lst = list(pricerelatives.dropna())
the_prod = reduce(operator.mul, lst)

编辑:删除所有 NaNs 并然后计算乘积而不是先将它们设置为 1 会更快。

非常非正式地,您仍然得到零的原因是,随着 [0, 1) 中值的数量与值 >= 1 的比率增加,乘积将更快地接近零。

def nnz_ratio(ratio, size=1000):
    n1 = ratio * size
    n2 = size - n1
    s1 = uniform(1, 2, size=n1)
    s2 = uniform(0, 1, size=n2)
    return Series(hstack((s1, s2)))

ratios = linspace(0.01, 1, 25)
ss = empty(len(ratios))

for i, ratio in enumerate(ratios):
    ss[i] = nnz_ratio(ratio).prod()

ss

给予:

array([  0.0000e+000,   0.0000e+000,   0.0000e+000,   0.0000e+000,
         0.0000e+000,   3.6846e-296,   2.6969e-280,   1.2799e-233,
         2.0497e-237,   4.9666e-209,   6.5059e-181,   9.8479e-171,
         7.7879e-125,   8.2696e-109,   9.3416e-087,   4.1574e-064,
         3.9266e-036,   4.1065e+004,   6.6814e+018,   7.1501e+040,
         6.2192e+070,   1.3523e+093,   1.0739e+110,   1.5646e+144,
         8.6361e+163])

编辑 #2:

如果要计算几何平均值,请使用

from scipy.stats import gmean

gm = gmean(pricerelatives.dropna())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    相关资源
    最近更新 更多