[python-nl] numpy & mask

Gijs Molenaar gijs at pythonic.nl
Tue Sep 25 16:09:52 CEST 2012


Hallo Pythonic mensen,

Ik heb een numpy snelheids probleem. TL;DR Waarom is rekenen met een
masked array zo langzaam? Of doe ik iets niet goed?

Ik heb een matrix met waardes, en ik wil iteratief alle waardes uit de
matrix maskeren boven een bepaalde sigma vanaf de median. het gaat
uiteindelijk om de RMS waarde van een signaal plaatje te berekenen.
Boeit voor de rest niet, maar dan weet je waar ik het voor gebruik.

Ik vond ergens in onze code base een stuk code die dit min of meer doet:

def clip(data, sigma=3):
    median = numpy.median(data)
    std = numpy.std(data)
    newdata = data[numpy.abs(data-median) <= sigma*std]
    if len(newdata) and len(newdata) != len(data):
        return clip(newdata, sigma)
    else:
        return newdata

Van de matrix die hier uit komt kan je makkelijk de RMS berekenen. maar
mijn eerste idee was dat het vrij langzaam zou zijn, omdat het recursief
elke keer een nieuwe array alloceert. Ik had het idee dat het maskeren
van je waardes veel sneller zou zijn. Maar als ik het stukje herschrijf
gebruik makende van maskedarrays [1] en vervolgens dit mask gebruik
wordt de code echt veel trager (+/- 8x). Ik las ergens dat MaskedArray
zo traag is omdat het native in Python wordt gedaan, omdat het vrij
lastig is mask operaties in low level C loops te doen [2], maar ik weet
niet of dat nou echt waar is. Ik heb een tijd zitten pielen om het toch
zo snel mogelijk te krijgen (zonder maskedarrays) en kom tot het
volgende stukje code:

def clip(data, sigma=3):
    mask = numpy.zeros(data.shape, bool)
    new_mask = numpy.zeros(data.shape, bool)
    masked = data
    while True:
        median = numpy.median(masked)
        std = numpy.std(masked)
        new_mask[numpy.abs(data - median) > sigma * std] = True
        diff = new_mask & ~mask
        mask = mask | new_mask
        if not diff.any():
            return mask
        masked = data[~mask]
        new_mask[:,:] = False

Dat uiteindelijk toch nog 2 keer zo traag is. Iemand een idee hoe ik het
toch sneller kan doen? En kunnen we maar beter masks niet gebruiken? Ik
heb veel met matlab gewerkt en ik had altijd het idee dat het gebruiken
van masks 'the way to go' is...

Thanks!

[1] http://docs.scipy.org/doc/numpy/reference/maskedarray.html
[2]
http://stackoverflow.com/questions/5760668/python-numpy-masked-arrays-are-very-slow
-- 
Gijs Molenaar
http://pythonic.nl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 259 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-nl/attachments/20120925/ff32ebeb/attachment.pgp>


More information about the Python-nl mailing list