2017-07-09 4 views
1

Ich habe eine mehrdimensionale numpy Array, die eine Reihe von Bildern ist. Warum führt die Berechnung des Bildkanals zu unterschiedlichen Ergebnissen, wenn das Achsenargument für np.mean verwendet wird?numpy mean multidimensionalen Array

>>> X = np.array(np.random.random((9999, 128, 128, 4)) * 1e5, dtype='float32') 
>>> X.shape 
(9999, 128, 128, 4) 
>>> mean_by_axis = np.mean(X, axis=(0, 1, 2)) 
array([ 13423.11523438, 13423.11523438, 13423.11523438, 13423.11523438], dtype=float32) 
>>> mean = np.mean(X[:, :, :, 0]) 
50001.297 

Ich erwarte mean_by_axis [0] == mean. Warum ist das nicht der Fall? Das gleiche gilt für die restlichen axis-3-Indizes 1, 2 und 3. Missverstehe ich, wie das Achsenargument in np.mean zu verwenden ist?

Mit numpy Version '1.12.1'

Ist es möglich, dass ich die float32 Akkumulator bin überfüllt? Zum Beispiel:

>>> X = np.random.random(size=(100, 128, 128, 4)) 
>>> np.mean(X, axis=(0, 1, 2)) 
array([ 0.49978557, 0.49985835, 0.50000321, 0.50015689])] 
>>> np.mean(X[:, :, :, 0]) 
0.49978556940636332 

Das sieht richtig aus. Wenn dies der Fall ist, warum überläuft die Slice-Methode nicht auch den Akkumulator und gibt das gleiche Ergebnis? Vielleicht verwendet die Slice-Methode einen float64-Akkumulator und die Achsenmethode einen float32-Akkumulator?

+0

Ich verwende die Achse wie im obigen Link beschrieben. Meine Frage bezieht sich darauf, warum das Achsenergebnis anders ist als das Scheibenergebnis. – bfb

Antwort

0

Ich kann nicht genau Ihr Ergebnis reproduzieren, da Sie Ihre Daten nicht zur Verfügung stellen, aber mit zufälligen Daten kann ich das Problem reproduzieren:

>>> import numpy as np 
>>> X = np.random.rand(9999, 128, 128, 4).astype('float32') 
>>> X.shape 
>>> np.mean(X, axis=(0, 1, 2)) 
array([ 0.10241024, 0.10241024, 0.10241024, 0.10241024], dtype=float32) 
>>> np.mean(X[:, :, :, 0]) 
0.50000387 
>>> np.mean(X[:, :, :, 0].flatten()) 
0.50000387 

Dies ist wahrscheinlich ein Fall unzureichender numerischer Präzision. Sie summieren (9999 * 128 * 128 = 163823616) Fließkommawerte, und die relative Genauigkeit eines float32 ist ~ 10^-7, so dass Sie die Grenzen der Genauigkeit überschreiten.

Ich würde Ihnen empfehlen, versuchen Sie Ihr Array zu Float64, die höhere Präzision hat, vor Aufruf Mittel und sehen, was passiert.

>>> np.mean(X.astype('float64'), axis=(0, 1, 2)) 
array([ 0.50000323, 0.50004907, 0.50003198, 0.49999848]) 
>>> np.mean(X[:, :, :, 0].astype('float64')) 
0.50000323305421812 
>>> np.mean(X[:, :, :, 0].flatten().astype('float64')) 
0.50000323305421812 
+0

Gleiches. Verwenden Sie größere Zahlen. Ich werde einen Code veröffentlichen, um morgen zu demonstrieren. – bfb

+0

Nun, ich reproduziert ein ähnliches Problem mit einfachen Zufallsdaten. Wie auch immer, ich habe ein numpy Problem erstellt, da es wie ein Bug aussieht: https://github.com/numpy/numpy/issues/9393 –

Verwandte Themen