6

タイムスタンプの配列があり、行列 X の 2 列目の行ごとに増加します。タイムスタンプの平均値を計算すると、最大値よりも大きくなります。ストレージに numpy memmap を使用しています。なぜこうなった?

>>> self.X[:,1]
memmap([  1.45160858e+09,   1.45160858e+09,   1.45160858e+09, ...,
     1.45997146e+09,   1.45997683e+09,   1.45997939e+09], dtype=float32)
>>> np.mean(self.X[:,1])
1.4642646e+09
>>> np.max(self.X[:,1])
memmap(1459979392.0, dtype=float32)
>>> np.average(self.X[:,1])
1.4642646e+09
>>> self.X[:,1].shape
(873608,)
>>> np.sum(self.X[:,1])
memmap(1279193195216896.0, dtype=float32)
>>> np.sum(self.X[:,1]) / self.X[:,1].shape[0]
memmap(1464264515.9120522)

編集: ここに memmap ファイルをアップロードしました。http://www.filedropper.com/x_2これが私がロードする方法です。

filepath = ...
shape = (875422, 23)
X = np.memmap(filepath, dtype="float32", mode="r", shape=shape)

# I preprocess X by removing rows with all 0s
# note this step doesn't affect the problem
to_remove = np.where(np.all(X == 0, axis=1))[0]
X = np.delete(X, to_remove, axis=0)
4

1 に答える 1

6

これは numpy または memmap の問題ではありません。float32問題は、正確には浮動小数点にあります。C++ などの他の言語でも同じエラーが発生することがわかります。

使用されるfloat32アキュムレータは、数値が追加されるにつれて不正確になります。

In [26]: a = np.ones((1024,1024), dtype=np.float32)*4567

In [27]: a.min()
Out[27]: 4567.0

In [28]: a.max()
Out[28]: 4567.0

In [29]: a.mean()
Out[29]: 4596.5264

これはnp.float64タイプでは発生しません (もう少し呼吸する余地があります)。

In [30]: a = np.ones((1024,1024), dtype=np.float64)*4567

In [31]: a.min()
Out[31]: 4567.0

In [32]: a.mean()
Out[32]: 4567.0

明示的に指定することでバッファmean()を使用することができます。float64

In [12]: a = np.ones((1024,1024), dtype=np.float32)*4567

In [13]: a.mean(dtype=np.float64)
Out[13]: 4567.0
于 2016-04-09T22:34:39.507 に答える