Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
talit:python_advanced [2023-08-11 14:36] – [Magic & Cheat Sheet] scatalit:python_advanced [2025-08-29 16:33] (aktuell) – [Numba] sca
Zeile 61: Zeile 61:
 In Jupyter-Notebooks kann man sogenannte **Magic-Befehle** verwenden, welche immer mit `%` beginnen. Diese und viele anderen wichtigen Befehle findet man im folgenden **Cheat Sheet:** In Jupyter-Notebooks kann man sogenannte **Magic-Befehle** verwenden, welche immer mit `%` beginnen. Diese und viele anderen wichtigen Befehle findet man im folgenden **Cheat Sheet:**
  
-{{:talit:jupyter_notebook_cheatsheet_edureka_image.png?nolink&300 }}+{{ :talit:jupyter_notebook_cheatsheet_edureka_image.png?nolink&300 |}}
  
 Klicke auf folgenden Link, um das Cheat Sheet als PDF herunterzuladen: Klicke auf folgenden Link, um das Cheat Sheet als PDF herunterzuladen:
Zeile 378: Zeile 378:
 Diese Funktionen bieten eine kompakte und elegante Möglichkeit, Transformationen auf Daten anzuwenden oder Elemente aus Sequenzen auszuwählen. Sie sind besonders nützlich in Situationen, in denen eine Schleife vermieden oder der Code auf eine Zeile reduziert werden soll. Diese Funktionen bieten eine kompakte und elegante Möglichkeit, Transformationen auf Daten anzuwenden oder Elemente aus Sequenzen auszuwählen. Sie sind besonders nützlich in Situationen, in denen eine Schleife vermieden oder der Code auf eine Zeile reduziert werden soll.
  
 +===== Numba =====
 +
 +Numba ist ein Just-in-Time (JIT) Compiler für Python, der Funktionen mit Hilfe von LLVM in Maschinencode übersetzt. Besonders nützlich ist Numba für **numerische Berechnungen mit NumPy**, da es diese **massiv beschleunigen** kann – auch durch **Parallelisierung**.
 +
 +Installation
 +<code bash>
 +pip install numba
 +</code>
 +
 +Tipps:
 +
 +   * **Vermeide Python-Objekte** (z. B. Listen, Dictionaries).
 +   * Nutze **NumPy-Arrays** und primitive Datentypen (z.B. int).
 +   * Verwende `numba.set_num_threads(n)` zur Kontrolle der Thread-Anzahl.
 +
 +
 +==== Beispiel: Prinzahlen ====
 +
 +Wir schauen einen Code an, der ermittelt, wie viele Primzahlen es bis und mit einer vorgegebenen Zahl `n_max` gibt. Die Funktion `is_prime()` wurde dabei möglichst ineffizient programmiert.
 +
 +Version 1 ist der ursprüngliche Code, ganz ohne numba. In Version 2 wurde der Code mit ganz wenigen einfachen Anpassungen ungeschrieben und mit numba parallelisiert. Dabei konnte die Laufzeit von 26.5s auf 0.4s reduziert werden!!!
 +
 +**Version 1:** Ursprünglicher Code ohne numba. Zeit: 26.5s
 +<code python>
 +n_max = 1e5
 +
 +def is_prime(x):
 +    for i in range(2,x):
 +        if x % i == 0:
 +            return False
 +    return True
 +
 +nr_primes = 0
 +for i in range(2,int(n_max)):
 +    if is_prime(i):
 +        nr_primes += 1
 +print(nr_primes)
 +</code>
 +
 +**Version 2:** Erste Optimierung mit numba. Zeit: 0.4s
 +<code python>
 +from numba import njit, prange
 +import numpy as np
 + 
 +@njit
 +def is_prime(x):
 +    for i in range(2,x):
 +        if x % i == 0:
 +            return False
 +    return True
 + 
 +@njit(parallel=True, fastmath=True)
 +def run():
 +    n_max = 3e4
 +    nr_primes = 0
 +    for i in prange(2,int(n_max)):
 +        if is_prime(i):
 +            nr_primes += 1
 +    return nr_primes
 + 
 +nr_primes = run()
 +print(nr_primes)
 +</code>
 +
 +Bemerkungen:
 +
 +   * @njit(parallel=True) aktiviert die **Parallelisierung**.
 +   * `range` ersetzt durch `prange` (parallel-range): prange sorgt dafür, dass die Schleife über i *parallel* ausgeführt wird.
 +
 +==== Beispiel: Numpy-Arrays ====
 +
 +Hier ein einfaches Beispiel, welches Numpy-Arrays involviert:
 +
 +**Version 1**: ohne numba (8.0s)
 +<code python>
 +
 +import numpy as np
 +
 +def berechne_sinus(x_vals):
 +    result = np.empty_like(x_vals)
 +    for i in range(len(x_vals)):
 +        result[i] = np.sin(x_vals[i])
 +    return result
 +
 +x = np.linspace(0, 2 * np.pi, int(1e7))
 +y = berechne_sinus(x)
 +</code>
 +
 +**Version 2**: mit numba (0.2s)
 +<code python>
 +import numpy as np
 +from numba import njit, prange
 +
 +@njit(parallel=True, fastmath=True)
 +def berechne_sinus(x_vals):
 +    result = np.empty_like(x_vals)
 +    for i in prange(len(x_vals)):
 +        result[i] = np.sin(x_vals[i])
 +    return result
 +
 +x = np.linspace(0, 2 * np.pi, int(1e7))
 +y = berechne_sinus(x)
 +</code>
  
  • talit/python_advanced.1691764584.txt.gz
  • Zuletzt geändert: 2023-08-11 14:36
  • von sca