2

我有一个由正数或 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

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

更新:感谢您的快速回复。不幸的是,它没有用:

    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
4

1 回答 1

3

这看起来像一个“错误” numpy;看这里。溢出时它不会升高。

这里有些例子:

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)

编辑:NaN删除所有s然后计算乘积而不是先将它们设置为 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())
于 2013-08-29T14:14:20.277 回答