Glidande medelvärde filter scipy
Hmmm, det verkar som att denna quoteasy att implementquot-funktion är faktiskt ganska lätt att bli fel och har främjat en bra diskussion om minneseffektivitet. Jag är glad att ha uppblåst om det betyder att veta att någonting har gjorts rätt. ndash Richard Sep 20 14 kl 19:23 NumPys brist på en viss domänspecifik funktion är kanske på grund av Core Teams disciplin och trovärdighet till NumPys primära direktiv: tillhandahålla en N-dimensionell array-typ. samt funktioner för att skapa och indexera dessa arrays. Liksom många fundamentella mål är den här inte liten, och NumPy gör det briljant. Den (mycket) större SciPy innehåller en mycket större samling domänspecifika bibliotek (kallas underpaket av SciPy devs) - till exempel numerisk optimering (optimera), signalprocessing (signal) och integralkalkyl (integrera). Min gissning är att den funktion du är ute efter är i minst en av SciPy-subpackagesna (scipy. signal kanske) men jag skulle först se i samlingen av SciPy scikits. identifiera relevanta scikit (er) och leta efter intresse av det där intresset. Scikits är självständigt utvecklade paket baserat på NumPySciPy och riktad till en viss teknisk disciplin (t. ex. scikits-image. Scikits-learn etc.) Flera av dessa var (särskilt den fina OpenOpt för numerisk optimering) högt ansedda, mogna projekt länge innan de väljer att vistas under den relativt nya scikits rubriken. Scikits hemsida gillade att ovanstående listar cirka 30 sådana scikits. även om åtminstone flera av dessa inte längre är aktiva. Efter detta råd skulle du leda till scikits-timeseries men det paketet är inte längre under aktiv utveckling. I själva verket har Pandas blivit AFAIK, de facto NumPy-baserade tidsseribiblioteket. Pandas har flera funktioner som kan användas för att beräkna ett glidande medelvärde. Det enklaste av dessa är förmodligen rullande. som du använder så här: Nu, ring bara funktionen rollingmean som passerar i Serieobjektet och en fönsterstorlek. vilket i mitt exempel nedan är 10 dagar. verifiera att det fungerade - t. ex. jämförda värden 10-15 i de ursprungliga serierna mot den nya serien slätad med rullande medelfunktionen Rollingmean tillsammans med ungefär ett dussintals annan funktion är informellt grupperade i Pandas dokumentation under rubrik flyttningsfönstret funktioner en andra relaterad grupp av funktioner i Pandas kallas exponentiellt vikttade funktioner (t. ex. ewma. som beräknar exponentiellt rörligt vägt genomsnitt). Det faktum att den andra gruppen inte ingår i de första (flyttbara fönsterfunktionerna) beror kanske på att de exponentiellt viktade transformationerna inte bygger på ett fastlängdsfönster. Jag vet att det här är en gammal fråga, men här är en lösning som inte använder någon extra datastrukturer eller bibliotek. Det är linjärt i antalet element i ingångslistan och jag kan inte tänka på något annat sätt att göra det mer effektivt (faktiskt om någon vet om ett bättre sätt att fördela resultatet, var god och låt mig veta). OBS! Det här skulle vara mycket snabbare med en numpy array istället för en lista, men jag ville eliminera alla beroenden. Det kan också vara möjligt att förbättra prestanda genom multi-threaded execution Funktionen förutsätter att ingångslistan är endimensionell, så var försiktig. UPD: Effektivare lösningar har föreslagits av Alleo och jasaarim. Du kan använda np. convolve för det: Modusargumentet anger hur du kan hantera kanterna. Jag valde det giltiga läget här för att jag tror det är hur de flesta förväntar sig att de ska fungera, men du kan ha andra prioriteringar. Här är en plot som illustrerar skillnaden mellan lägena: svarat mar 24 14 kl 22:01 Jag gillar den här lösningen eftersom den är ren (en rad) och relativt effektiv (arbetet görs i numpy). Men Alleo39s quotEfficient solutionquot med numpy. cumsum har bättre komplexitet. ndash Ulrich Stern Sep 25 15 på 0:31 Du kan beräkna ett löpande medelvärde med: Lyckligtvis innehåller numpy en convolve-funktion som vi kan använda för att påskynda saker. Det löpande medelvärdet motsvarar att convolving x med en vektor som är N long, med alla medlemmar lika med 1N. Den numpy implementeringen av convolve inkluderar starttidspunkten, så du måste ta bort de första N-1 poängen: På min maskin är den snabba versionen 20-30 gånger snabbare beroende på längden på ingångsvektorn och storleken på medelfönstret . Observera att convolve inkluderar ett samma läge som verkar som att det borde ta itu med det startövergående problemet, men det delar upp det mellan början och slutet. Det tar bort övergången från slutet, och början har inte en. Tja, jag antar att det är en fråga om prioriteringar, jag behöver inte samma antal resultat på bekostnad av att få en sluttning mot noll som inte finns i data. BTW, här är ett kommando för att visa skillnaden mellan lägena: 393939, 39same39, 39valid39) plot (convolve (ones (200,)), ones (50,) 4750, modem)) för m i lägen axel (-10, 251, -,1, 1.1) legend (lägen, loc39lower center39) (med pyplot och numpy importerad). ndash lapis Mar 24 14 kl 13:56 pandor är mer lämpade för detta än NumPy eller SciPy. Dess funktion rollingmean gör jobbet bekvämt. Det returnerar också en NumPy-array när ingången är en array. Det är svårt att slå rollingmean i prestanda med någon anpassad ren Python-implementering. Här är ett exempel på prestanda mot två av de föreslagna lösningarna: Det finns också bra alternativ för hur man hanterar kantvärdena. I39m är alltid irriterad av signalbehandlingsfunktionen som returnerar utsignaler av annan form än ingångssignalerna när båda ingångarna och utgångarna är av samma natur (t ex båda tidssignalerna). Det bryter korrespondensen med relaterad oberoende variabel (t ex tid, frekvens) som gör plottning eller jämförelse inte en direkt fråga. ändå, om du delar känslan, kanske du vill ändra de sista raderna i den föreslagna funktionen som ynp. convolve (ww. sum (), s, mode39same39) returnera ywindowlen-1 :-( windowlen-1) ndash Christian O39Reilly Aug 25 15 kl 19:56 Lite sent till festen, men Ive gjorde min egen lilla funktion som inte sitter runt ändarna eller dynorna med nollor som sedan används för att hitta medeltalet också. Som en ytterligare behandling är att den också samplar signalen på linjärt åtskilda punkter. Anpassa koden på viljan för att få andra funktioner. Metoden är en enkel matrismultiplikation med en normaliserad gausskärna. En enkel användning på en sinusformad signal med tillsatt normalt distribuerat ljud: Den här frågan är nu ännu äldre än när NeXuS skrev om det förra månaden, men jag tycker om hur hans kod hanterar kantfall. Men eftersom det är ett enkelt glidande medel, ligger resultaten bakom de data de tillämpar. Jag trodde att det handlar om kantfall på ett mer tillfredsställande sätt än NumPys lägen som är giltiga. samma. och fullt kan uppnås genom att tillämpa ett liknande tillvägagångssätt för en convolution () - baserad metod. Mitt bidrag använder ett centralt löpande medelvärde för att anpassa sina resultat med deras data. När det finns två få punkter tillgängliga för det fullstora fönstret som ska användas, beräknas löpande medelvärden beräknas från successivt mindre fönster vid kanterna av matrisen. Egentligen, från successivt större fönster, men det är en implementeringsdetalj. Det är relativt långsamt eftersom det använder convolve (). och kan troligen bli spruced upp ganska mycket av en sann Pythonista, men jag tror att tanken står. svarade 2 jan kl 0:28 np. convolve är trevligt men långsamt när fönstervidden blir stor. Vissa svar ger mer effektiva algoritmer med np. cumsum men verkar inte kunna hantera kanten värden. Jag har själv genomfört en algoritm som kan hantera detta problem bra om det här problemet förklaras som: Input parameter mergenum kan anses som 2 fönsterbredd 1. Jag vet att den här koden är lite oläslig om du tycker att den är användbar och vill ha några expanations, var god och låt mig veta och jag uppdaterar det här svaret. (Eftersom skrivning kan en förklaring kunna kosta mig mycket tid, hoppas jag att jag bara gör det när någon behöver det. Vänligen förlåt mig för min lathet :)) Om du bara är intresserad av sin ursprungliga version: Dess ännu mer oläsliga: den första lösningen blir av med kanten problem med padding nollor runt matrisen, men den andra lösningen som skickas här hanterar det på ett tufft och direkt sätt :) lapis ja, men vi kan säga att du använder cumsummetoden på det första fältet och räddar din rullande genomsnittliga matris för nästa kryssrutan. varje ficka därefter måste du bara lägga till det senaste glidande medelvärdet till din rullande grupp i lager. Med hjälp av den här metoden beräknar du inte om saker du redan har beräknat: På först tickar du cumsum därefter lägger du bara in kvoten av den sista perioden elementsquot som är 2x snabbare för alla efterföljande fästingar. ndash litepresence 10 jun 16 kl 12:29 Om du väljer att rulla din egen, istället för att använda ett befintligt bibliotek, var vänlig medveten om flytande punktfel och försök att minimera effekterna: Om alla dina värden är ungefär samma storleksordning , då kommer detta att bidra till att bevara precision genom att alltid lägga till värden av ungefär samma storheter. I min sista meningen försökte jag ange varför det hjälper till att flytta punktfelet. Om två värden är ungefär samma storleksordning, så lägger du till dem förlorar mindre precision än om du lagt till ett mycket stort antal till en mycket liten. Koden kombinerar quotadjacentquot-värden på ett sådant sätt att även mellanliggande summor alltid ska vara rimligen nära i storleksordningen för att minimera floating point-felet. Ingenting är dåligt bevis, men den här metoden har sparat ett par väldigt dåligt genomförda projekt inom produktionen. ndash Mayur Patel Dec 15 14 kl 17:22 Alleo: Istället för att göra en tillägg per värde, så gör du två. Beviset är detsamma som det bit-flipping-problemet. Men punkten i detta svar är inte nödvändigtvis prestanda, men precision. Minnesanvändning för genomsnittliga 64-bitars värden skulle inte överstiga 64 element i cacheminnet, så det är också vänligt i minnesanvändning. ndash Mayur Patel Dec 29 14 kl 17: 04Följande exempel ger ett glidande medelvärde av föregående WINDOW-värden. Vi avkortar de första värdena (WINDOW -1) eftersom vi kan hitta genomsnittet före dem. (Standardbeteendet för konvolvering är att anta att värden före starten av vår sekvens är 0). (Mer formellt konstruerar vi sekvensen y för sekvensen x där yi (xi x (i1) 8230. x (in)) n) Detta utnyttjar numpy8217s convolution-funktionen. Detta är en allmän rörelse medellägeoperation. Ändring av viktningar gör vissa värden viktigare motsättning lämpligt kan du se genomsnittet som runt punkt snarare än för punkt. I stället för trunkerande värden kan vi fixa de ursprungliga värdena på plats, som illustreras i det här exemplet:
Comments
Post a Comment