2015-05-13 1 views
5

mam jedną prostą tablicę 3D a1, a jego zamaskowanej analogowych a2:`numpy.mean` stosować krotki jako` axis` argumentu: nie działa z zamaskowanego tablicy

import numpy 

a1 = numpy.array([[[ 0.00, 0.00, 0.00], 
        [ 0.88, 0.80, 0.78], 
        [ 0.75, 0.78, 0.77]], 

        [[ 0.00, 0.00, 0.00], 
        [ 3.29, 3.29, 3.30], 
        [ 3.27, 3.27, 3.26]], 

        [[ 0.00, 0.00, 0.00], 
        [ 0.41, 0.42, 0.40], 
        [ 0.42, 0.43, 0.41]]]) 


a2 = numpy.ma.masked_equal(a1, 0.) 

Chcę wykonać Średnią wartość tego szeregu wzdłuż kilku osi w czasie (to jest specyficzny, nieudokumentowana zastosowanie axis argumencie numpy.mean patrz np here na przykład):

numpy.mean(a1, axis=(0, 1)) 

ten działa dobrze z a1, ale pojawia się następujący komunikat o błędzie z zamaskowanym tablicy a2:

TypeError: tuple indices must be integers, not tuple 

I uzyskać ten sam błąd z zamaskowanej wersji numpy.ma.mean(a2, axis=(0, 1)) lub jeśli zdemaskować tablicę przez a2[a2.mask]=0.

Używam krotki dla argumentu axis w numpy.mean ponieważ w rzeczywistości nie jest on kodowany na stałe (to polecenie jest stosowane do tablic o potencjalnie różnej liczbie wymiarów, zgodnie z którymi krotka jest dostosowywana).

Wystąpił problem z numpy wersja 1.9.1 i 1.9.2.

+0

Czy możesz podać przykład, który można wyciąć i wkleić? – atomh33ls

+0

Zgodnie z [docs] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html) argumentem osi jest int. Co oznacza przekazywanie krotki zamiast int? – ypx

+0

Nie powinieneś używać ["ma' wersji" mean'] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.mean.html) dla zamaskowanego argumentu tablicowego ? – user2357112

Odpowiedz

5

Dla argumentu MaskedArray, numpy.mean wywołania MaskedArray.mean, który nie obsługuje argumentu krotki axis. Można uzyskać poprawne zachowanie przez reimplementing MaskedArray.mean w zakresie operacji, które wykonują krotki wsparcia dla axis:

def mean(a, axis=None): 
    if a.mask is numpy.ma.nomask: 
     return super(numpy.ma.MaskedArray, a).mean(axis=axis) 

    counts = numpy.logical_not(a.mask).sum(axis=axis) 
    if counts.shape: 
     sums = a.filled(0).sum(axis=axis) 
     mask = (counts == 0) 
     return numpy.ma.MaskedArray(data=sums * 1./counts, mask=mask, copy=False) 
    elif counts: 
     # Return scalar, not array 
     return a.filled(0).sum(axis=axis) * 1./counts 
    else: 
     # Masked scalar 
     return numpy.ma.masked 

lub, jeśli jesteś gotów polegać na MaskedArray.sum pracy z krotki axis (które prawdopodobnie są, biorąc pod uwagę że używasz nieudokumentowane zachowanie od numpy.mean)

def mean(a, axis=None): 
    if a.mask is numpy.ma.nomask: 
     return super(numpy.ma.MaskedArray, a).mean(axis=axis) 

    sums = a2.sum(axis=axis) 
    counts = numpy.logical_not(a.mask).sum(axis=axis) 
    result = sums * 1./counts 

gdzie jesteśmy powołując się na MaskedArray.sum obsłużyć maskę.

Mam tylko lekko przetestowane te funkcje; przed ich użyciem upewnij się, że faktycznie działają i napisz kilka testów. Na przykład, jeśli wyjście jest 0-wymiarowe i nie ma żadnych wartości maskowanych, to czy wyjście jest maską 0D czy skalarem, zależy od tego, czy maska ​​wejściowa to nomask czy tablica wszystkich fałszywych. Działa to tak samo jak domyślne zachowanie MaskedArray.mean, ale może nie być tym, co chcesz; Podejrzewam, że domyślne zachowanie jest błędem.