3

这个问题与这篇文章非常相似- 但不完全是

我在 .csv 文件中有一些数据。数据精确到第 4 位 (#.####)。

在 Excel 或 SAS 中计算平均值会给出精确到第 5 位 (#.#####) 的结果,但使用 numpy 会给出:

import numpy as np
data = np.recfromcsv(path2file, delimiter=';', names=['measurements'], dtype=np.float64)
rawD = data['measurements']
print np.average(rawD)

给出这样的数字

#.#####999999999994

明明有什么不对。。

使用

from math import fsum
print fsum(rawD.ravel())/rawD.size

#.#####

np.average 中是否有我设置错误的内容_______?


奖金信息:

我只处理数组中的 200 个数据点


更新

我想我应该更清楚地说明我的情况。

我的csv中有数字4.2730(给出4位小数精度 - 即使第4位总是为零[不是主题的一部分,所以不要介意])

通过 numpy 计算平均值/平均值给了我这个

4.2516499999999994

这给出了一个打印

>>>print "%.4f" % np.average(rawD)
4.2516

在 Excel 或 SAS 中的同一件事给了我这个:

4.2517

我实际上认为这是真正的平均值,因为它发现它是 4.25165。这段代码也说明了这一点:

answer = 0
for number in rawD:
    answer += int(number*1000)
print answer/2
425165

那么我如何告诉 np.average() 计算这个值___?


我有点惊讶 numpy 对我这样做......我认为我只需要担心如果我正在处理 16 位数字。没想到小数点后四位的四舍五入会受此影响。

我知道我可以使用

fsum(rawD.ravel())/rawD.size

但我还有其他东西(比如标准)我想以相同的精度计算

更新 2

我想我可以通过

>>>print "%.4f" % np.float64("%.5f" % np.mean(rawD))
4.2416

这并没有解决这个案子。然后我尝试了

>>>print "%.4f" % float("4.24165")
4.2416

啊哈!格式化程序中有一个错误:问题 5118

老实说,我不在乎 python 是否将 4.24165 存储为 4.241649999 ......它仍然是一个舍入错误 - 不管是什么。

如果解释者能弄清楚如何显示数字

>>>print float("4.24165")
4.24165

那么格式化程序也应该在四舍五入时处理该数字..

它仍然没有改变我有一个四舍五入问题的事实(现在使用格式化程序和numpy)

如果您需要一些数字来帮助我,那么我制作了这个修改后的 .csv 文件:

从这里下载

(我知道这个文件没有我之前解释的位数,并且平均值在末尾给出 ..9988 而不是 ..9994 - 它已修改)

猜猜我的问题归结为如何获得一个字符串输出,就像我使用 excel 给我的那样=average()

在此处输入图像描述

如果我选择仅显示 4 位数字,则让它正确四舍五入

在此处输入图像描述

我知道这对某些人来说可能看起来很奇怪。但我有理由想要重现 Excel 的行为。

任何帮助将不胜感激,谢谢。

4

2 回答 2

3

要获得精确的十进制数,您需要使用十进制算术而不是二进制。Python为此提供了十进制模块

如果您想继续使用 numpy 进行计算并简单地对结果进行四舍五入,您仍然可以使用decimal. 您分两步完成,四舍五入到大量数字以消除累积误差,然后四舍五入到所需的精度。该quantize方法用于舍入。

from decimal import Decimal,ROUND_HALF_UP
ten_places = Decimal('0.0000000001')
four_places = Decimal('0.0001')
mean = 4.2516499999999994
print Decimal(mean).quantize(ten_places).quantize(four_places, rounding=ROUND_HALF_UP)
4.2517
于 2013-08-02T16:28:37.437 回答
0

平均值的结果值为双倍。当您打印出双精度时,默认情况下会打印所有数字。你在这里看到的是有限数字精度的结果,这不是numpy的问题,而是一般的计算问题。当您关心浮点值的表示时,请使用"%.4f" % avg_val. 还有一个有理数包,以避免将分数表示为实数,但我想这不是你要找的。

对于您的第二条语句,手动汇总所有值然后除以它,我想您使用的是 python 2.7,并且您的所有输入值都是整数。这样,您将有一个整数除法,它会截断点之后的所有内容,从而产生另一个整数值。

于 2013-07-30T11:08:22.223 回答