Saturday 21 October 2017

Flytting Gjennomsnitt Filter Scipy


Hmmm, det virker som dette quoteasy å implementquot-funksjonen er faktisk ganske enkelt å bli feil og har fremmet en god diskusjon om minneeffektivitet. Jeg er glad for å ha oppblåst hvis det betyr å vite at noe har blitt gjort riktig. ndash Richard Sep 20 14 kl 19:23 NumPys mangel på en bestemt domenespesifikk funksjon er kanskje på grunn av Core Teams disiplin og troskap til NumPys hoveddirektiv: gi en N-dimensjonal array type. samt funksjoner for å opprette og indeksere disse arrays. Som mange grunnleggende mål er denne ikke liten, og NumPy gjør det glimrende. Den (mye) større SciPy inneholder en mye større samling av domenespesifikke biblioteker (kalt delpakker med SciPy devs) - for eksempel numerisk optimalisering (optimalisering), signalprosessering (signal) og integralkalkulator (integrere). Min gjetning er at funksjonen du er ute etter, er i minst en av SciPy-subpackages (scipy. signal kanskje), men jeg vil se først ut i samlingen av SciPy scikits. identifiser relevante scikit (er) og se etter interessens funksjon der. Scikits er selvstendig utviklede pakker basert på NumPySciPy og rettet mot en bestemt teknisk disiplin (f. Eks. Scikits-image. Scikits-learn etc.) Flere av disse var (spesielt den fantastiske OpenOpt for numerisk optimalisering) høyt ansett, modne prosjekter lange før du velger å bo under de relativt nye scikits rubric. Scikits hjemmeside likte å overliste omtrent 30 slike scikits. selv om minst flere av dem ikke lenger er under aktiv utvikling. Etter dette rådene vil du lede til scikits-timeseries, men denne pakken er ikke lenger under aktiv utvikling. Pandas er faktisk blitt AFAIK, de facto NumPy-baserte tidsseriebiblioteket. Pandas har flere funksjoner som kan brukes til å beregne et glidende gjennomsnitt. Det enkleste av disse er trolig rullende. som du bruker slik: Nå bare ring funksjonen rullende mens passerer i Serie objektet og en vindu størrelse. som i mitt eksempel nedenfor er 10 dager. bekreft at det virket - f. eks. sammenlignet verdier 10-15 i den opprinnelige serien versus den nye serien jevnet med rullende middel Funksjonen rullende mean sammen med omtrent et dusin eller annen funksjon er informelt gruppert i Pandas dokumentasjon under rubrikk flyttingsvinduet fungerer en andre relatert gruppe funksjoner i Pandas refereres til som eksponentielt vektede funksjoner (f. eks. ewma. som beregner eksponentielt flytende vektet gjennomsnitt). Det faktum at denne andre gruppen ikke er inkludert i de første (flyttbare vindufunksjonene) er kanskje fordi de eksponentielt vektede transformasjonene ikke stole på et fastlengtingsvindu. Jeg vet at dette er et gammelt spørsmål, men her er en løsning som ikke bruker noen ekstra datastrukturer eller biblioteker. Det er lineært i antall elementer i inngangslisten, og jeg kan ikke tenke på noen annen måte å gjøre det mer effektivt (faktisk hvis noen vet om en bedre måte å tildele resultatet, vennligst gi meg beskjed). MERK: Dette ville være mye raskere med et numpy array i stedet for en liste, men jeg ønsket å eliminere alle avhengigheter. Det vil også være mulig å forbedre ytelsen ved multi-threaded utførelse Funksjonen forutsetter at inntallelisten er endimensjonal, så vær forsiktig. UPD: Effektivere løsninger har blitt foreslått av Alleo og jasaarim. Du kan bruke np. convolve for det: Modusargumentet angir hvordan du kan håndtere kantene. Jeg valgte den gyldige modusen her fordi jeg tror det er slik de fleste forventer å kjøre, betyr å jobbe, men du kan ha andre prioriteringer. Her er et diagram som illustrerer forskjellen mellom modiene: svarte 24. mars kl. 22:01 Jeg liker denne løsningen fordi den er ren (en linje) og relativt effektiv (arbeid gjort inne numpy). Men Alleo39s quotEfficient solutionquot bruker numpy. cumsum har bedre kompleksitet. ndash Ulrich Stern Sep 25 15 på 0:31 Du kan beregne et løpende middel med: Heldigvis inneholder numpy en convolve-funksjon som vi kan bruke til å øke hastigheten. Det løpende gjennomsnittet er ekvivalent med å inkludere x med en vektor som er N lang, med alle medlemmer lik 1N. Den numpy implementeringen av convolve inkluderer startovergangen, så du må fjerne de første N-1 poengene: På min maskin er den raske versjonen 20-30 ganger raskere, avhengig av lengden på inngangsvektoren og størrelsen på gjennomsnittsvinduet . Vær oppmerksom på at convolve inkluderer en samme modus som virker som om den burde adressere det startende forbigående problemet, men det splitter det mellom begynnelsen og slutten. Det fjerner forbigående fra slutten, og begynnelsen har ikke en. Vel, jeg antar det er et spørsmål om prioriteringer, jeg trenger ikke samme antall resultater på bekostning av å få en skråning mot null som ikke er der i dataene. BTW, her er en kommando for å vise forskjellen mellom modusene: 393939, 39same39, 39valid39) plot (convolve (ones (200,)), ones (50,) 4750, modem)) for m i moduser akse (-10, 251, -.1, 1.1) legenden (moduser, loc39lower center39) (med pyplot og numpy importert). ndash lapis Mar 24 14 kl 13:56 pandas er mer egnet for dette enn NumPy eller SciPy. Funksjonen rollingmean gjør jobben beleilig. Det returnerer også et NumPy-array når inngangen er en matrise. Det er vanskelig å slå rollingmean i ytelse med enhver tilpasset ren Python implementering. Her er et eksempel på ytelse mot to av de foreslåtte løsningene: Det er også gode alternativer for hvordan man skal håndtere kantenverdiene. I39m er alltid irritert av signalbehandlingsfunksjonen som returnerer utgangssignaler av forskjellig form enn inngangssignalene når begge innganger og utganger er av samme natur (for eksempel begge tidssignaler). Den bryter korrespondansen med relatert uavhengig variabel (for eksempel tid, frekvens) som gjør plotting eller sammenligning ikke en direkte sak. Uansett, hvis du deler følelsen, vil du kanskje endre de siste linjene i den foreslåtte funksjonen som ynp. convolve (ww. sum (), s, mode39same39) returnere ywindowlen-1 :-( windowlen-1) ndash Christian O39Reilly Aug 25 15 kl 19:56 Litt sent til festen, men jeg har laget min egen lille funksjon som ikke vikler rundt endene eller pads med nuller som da brukes til å finne gjennomsnittet også. Som en videre behandling er at den også prøver å samplere signalet ved lineært avstand. Tilpass koden på vilkårlig måte for å få andre funksjoner. Metoden er en enkel matriksmultiplikasjon med en normalisert gausskjerne. En enkel bruk på et sinusformet signal med tilsatt normal distribuert støy: Dette spørsmålet er nå enda eldre enn da NeXuS skrev om det i forrige måned, MEN jeg liker hvordan hans kode omhandler kantsaker. Men fordi det er et enkelt glidende gjennomsnitt, går resultatene etter de dataene de søker på. Jeg trodde det handlet om kantsaker på en mer tilfredsstillende måte enn NumPys-modusene var gyldige. samme. og full kunne oppnås ved å anvende en lignende tilnærming til en konvolusjon () basert metode. Mitt bidrag bruker et sentralt løpende gjennomsnitt for å justere resultatene med dataene sine. Når det er to få poeng tilgjengelig for vinduet i full størrelse som skal brukes, beregnes løpende gjennomsnitt fra suksessivt mindre vinduer ved kantene av arrayet. Egentlig fra suksessivt større vinduer, men det er en implementeringsdetalj. Det er relativt sakte fordi det bruker convolve (). og kan sannsynligvis bli spruced opp ganske mye av en ekte Pythonista, men jeg tror at ideen står. svaret 2. januar klokka 0:28 np. convolve er fint, men sakte når vinduets bredde blir stor. Noen svar gir mer effektive algoritmer med np. cumsum, men synes ikke å håndtere kantenverdier. Jeg har selv implementert en algoritme som kan håndtere dette problemet godt, hvis dette problemet er erklært som: Input parameter mergenum kan betraktes som 2 windowwidth 1. Jeg vet at denne koden er litt ulæselig hvis du finner det nyttig og vil ha noen utvidelser, vennligst gi meg beskjed og jeg oppdaterer dette svaret. (Siden å skrive en forklaring kan det koste meg mye tid, jeg håper jeg bare gjør det når noen trenger det. Vennligst tilgi meg for min dovenskap :)) Hvis du bare er interessert i sin opprinnelige versjon: Den er enda mer ulæselig: den første løsningen blir kvitt kantenproblemet ved å putte nuller rundt i matrisen, men den andre løsningen oppført her håndterer den på en tøff og direkte måte :) lapis ja, men vi kan si at du bruker cumsum-metoden på det første krysset og lagre rullende gjennomsnittlig matrise for neste kryss. hvert kryss etterpå må du bare legge til den siste glidende gjennomsnittsverdien til rullingsystemet ditt i lager. Ved å bruke denne metoden, beregner du ikke ting du allerede har beregnet: På først krysser du cumsum etterpå, legger du bare inn kvoten av den siste perioden elementsquot som er 2x raskere for alle etterfølgende flått. ndash litepresence Jun 10 16 at 12:29 Hvis du velger å rulle din egen, i stedet for å bruke et eksisterende bibliotek, vær så oppmerksom på flytende punktfeil og prøv å minimere effektene: Hvis alle verdiene dine er omtrent like stor størrelsesorden , da vil dette bidra til å bevare presisjon ved alltid å legge til verdier av omtrent like storheter. I min siste setning forsøkte jeg å indikere hvorfor det hjelper flytende punktfeil. Hvis to verdier er omtrent samme størrelsesorden, blir det mindre presis enn å legge til et veldig stort tall til en liten størrelse. Koden kombinerer quotadjacentquot-verdier på en slik måte at selv mellomliggende beløp alltid skal være rimelig nær i størrelsesorden, for å minimere flytpunktsfeilen. Ingenting er dumt bevis, men denne metoden har reddet et par svært dårlig implementerte prosjekter i produksjonen. ndash Mayur Patel Dec 15 14 at 17:22 Alleo: I stedet for å gjøre ett tillegg per verdi, vil du gjøre to. Beviset er det samme som bit-flipping problemet. Imidlertid er poenget med dette svaret ikke nødvendigvis ytelse, men presisjon. Minnebruk for gjennomsnittlige 64-biters verdier vil ikke overstige 64 elementer i hurtigbufferen, så det er også vennlig i minnebruk. ndash Mayur Patel Des 29 14 kl 17: 04Følgende eksempler gir et glidende gjennomsnitt av de foregående WINDOW-verdiene. Vi truncate de første (WINDOW -1) verdiene siden vi kan finne gjennomsnittet før dem. (Standard oppførsel for konvolusjon er å anta at verdiene før starten av vår sekvens er 0). (Mer formelt konstruerer vi sekvensen y for sekvensen x hvor yi (xi x (i1) 8230. x (in)) n) Dette gjør bruk av numpy8217s convolution-funksjon. Dette er en generell bruk av glidende gjennomsnittlig operasjon. Endring av vektinger gjør noen verdier mer viktige motsetning på riktig måte, slik at du kan se gjennomsnitt som rundt punkt i stedet for før punkt. I stedet for avkortede verdier kan vi fikse de opprinnelige verdiene på plass, som illustrert i dette eksemplet:

No comments:

Post a Comment