[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