PythonProgramozás

Lokális minimumok 1D Numpy tömbökben

2021. október 10. 12:18 - Madg

Hogyan lehet megtalálni a lokális minimumokat az 1D NumPy tömbökben?

 

Egy függvény szélső helye az az x érték, amelynél a függvény értéke a legnagyobb vagy legkisebb egy adott intervallumban vagy a teljes értelmezési tartományban.
Az f(x)-nek akkor van lokális maximuma x0-ban, ha van olyan környezet, hogy ebben a környezetben bármely x-re f(x) ≥ f(x0). Van f(x) lokális minimuma x0-ban, ha van olyan környezet, hogy ebben a környezetben bármely x-re f(x) ≤ f(x0).
Egy f(x) függvénynek ugyanis több lokális szélsőértéke is lehet. Minden globális szélsőérték egyben lokális is, de fordítva természetesen ez nem igaz.
Ezeket az értékeket gyakran nevezik "csúcsoknak", mert ezek a függvény grafikonján megjelenő "hegyek" és "völgyek" csúcsai.
Ezeknek a pontoknak a gyakorlati alkalmazása alapvető fontosságú, például a képfeldolgozásban és a jelfeldolgozásban, például a földönkívüli üzenetek felderítésében! :)
Ebben a cikkben megnézünk néhány egyszerű módszert arra, hogyan találhatunk mélyedéseket egy numpy tömbben csak a numpy beépített függvényeivel, vagy a scipy könyvtár segítségével.

Az összes minimum egy 1D numpy tömbben.


A helyi minimumok olyan pontok, amelyeket mindkét oldalon nagyobb értékek vesznek körül.
Természetesen sokféleképpen megoldható a feladat, használhatsz tiszta numpy-t, végighaladhatsz az adatokon, vagy használhatod a scipy könyvtárat.
A Githubon találtam egy remek megoldást, Benjamin Schmidt munkáját, ami nagyon jól mutatja a lokális szélsőérték definícióját.


1. módszer: A numpy.where használatával

Kód:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace (0, 50, 1000)
y = 0.75 * np.sin(x)

peaks = np.where((y[1:-1] > y[0:-2]) * (y[1:-1] > y[2:]))[0] + 1
dips = np.where((y[1:-1] < y[0:-2]) * (y[1:-1] < y[2:]))[0] + 1


plt.plot (x, y)
plt.plot (x[peaks], y[peaks], 'o')
plt.plot (x[dips], y[dips], 'o')

plt.show()

 

A fentiekben egy listát készítünk az összes olyan indexről, ahol y[i] értéke nagyobb, mint mindkét szomszédja.
Nem ellenőrzi a végpontokat, amelyeknek csak egy-egy szomszédjuk van.
A plusz +1 a végén azért szükséges, mert a where az y[1:-1] szeleten belüli indexeket találja meg, nem pedig a teljes y tömböt. A [0] azért szükséges, mert a where egy tömbökből álló tuple-t ad vissza, ahol az első elem a kívánt tömb.
A matplotlib könyvtárat használjuk a grafikon elkészítéséhez.

2. módszer: A numpy.diff használata

 

A megoldás másik egyszerű megközelítése a numpy beépített függvényének, a "numpy.diff"-nek a használata.

Kód:

 

import numpy as np
# define an array

arr = np.array([1, 3, 7, 1, 2, 6, 0, 1, 6, 0, -2, -5, 18])

# What "numpy.diff" does, and what is the type of the result?

#print((np.diff(arr), type(np.diff(arr))))

# What "numpy.sign" does?

#print(np.sign(np.diff(arr)))


peaks = np.diff(np.sign(np.diff(arr)))

#print(peaks)

local_minima_pos = np.where(peaks == 2)[0] + 1
print(local_minima_pos)

 

Definiálunk egy 1D tömböt "arr", majd jön egy egysoros. Ebben először is kiszámítjuk az egyes elemek közötti különbségeket. (np.diff(arr). Ezután a "numpy.sign" függvényt használjuk ezen a tömbön, így megkapjuk a különbségek előjelét. (azaz: -1 vagy 1). Az egészet átadjuk egy másik "numpy.diff" függvénynek, amely +2 vagy -2 vagy 0 értéket ad vissza. 0 érték folyamatos csökkenést vagy növekedést, -2 érték maximumot, +2 érték pedig minimumot jelez. Most már megvannak a csúcsok, és a numpy.where megmondja a pozíciókat. (Figyeljük meg a +1-et a sor végén, ez azért van, mert a csúcsok tömb 0. eleme az arr tömb 0. és 1. eleme közötti különbség. A [0] azért szükséges, mert a "numpy.where" egy tömbökből álló tuple-t ad vissza, ahol az első elem az általunk kívánt tömb).

3. módszer: Megoldás scipy-vel:


Az utolsó példában azt szeretném bemutatni, hogy a scipy könyvtár segítségével hogyan oldható meg a probléma egyetlen sorban.

Kód:

import numpy as np

from scipy.signal import argrelextrema

 

x = np.linspace (0, 50, 100)

y = np.sin(x)

 

#print(y)

 

print(argrelextrema(y, np.less))

 

A következő bejegyzésben a 2D-s tömbök lokális minimumaival folyatatom.

 

 


 

 

Szólj hozzá!

A bejegyzés trackback címe:

https://pythonprogramozas.blog.hu/api/trackback/id/tr6316716418

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása