Commit 4c3055f2 authored by Jochen Schulz's avatar Jochen Schulz
Browse files

fix

parent a8d50e76
Pipeline #277709 canceled with stage
in 1 minute and 24 seconds
......@@ -4,8 +4,10 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
......@@ -19,25 +21,27 @@ erlaubt, `dot` oder `@` zu benutzen.
b) Schreiben Sie dann neben der seriellen Implementation auch eine, die parallel funktioniert, und vergleichen Sie die Geschwindigkeiten. Schauen Sie sich an, welche potentiellen Effekte die Berechnung langsamer oder schneller machen.
```{code-cell}
:tags: ['hide-cell']
```{code-cell} ipython3
:tags: [hide-cell]
import numpy as np
```
```{code-cell}
:tags: ['hide-cell']
```{code-cell} ipython3
:tags: [hide-cell]
N = 100000
A = np.random.randn(1000,N)
x = np.random.randn (N)
print('numpy intern')
trs = A.dot(x)
%timeit A.dot(x)
trs = A @ x
%timeit A @ x
```
```{code-cell} ipython3
:tags: [hide-cell]
```{code-cell}
:tags: ['hide-cell']
print('numpy:')
def mvb(M,v):
return (M * v[None, :]).sum(axis=1)
......@@ -47,52 +51,92 @@ res = mvb(A,x)
print(np.linalg.norm(res - trs))
```
```{code-cell}
:tags: ['hide-cell']
```{code-cell} ipython3
:tags: [hide-cell]
import numba as nu
print('numpy+numba:')
@nu.njit('float64[:](float64[:,:],float64[:,:])')
# Hier muss der slice ersetzt werden durch expand_dims, weil er durch numba nicht effizient
# übersetzt werden konnte. expand_dims ist jedoch identisch zum slice [None, :], in dem Sinne
# das er eine Dimension hinzufügt.
@nu.njit('float64[:](float64[:,:],float64[:])')
def mvb(M,v):
return (M * v).sum(axis=1)
return (M * np.expand_dims(v, 0)).sum(axis=1)
resn = mvb(A,x[None, :])
%timeit mvb(A,x[None, :])
resn = mvb(A,x)
%timeit mvb(A,x)
print(np.linalg.norm(resn - trs))
```
```{code-cell}
:tags: ['hide-cell']
```{code-cell} ipython3
:tags: [hide-cell]
import dask.array as da
CD = da.from_array(A, chunks=(100,'auto'))
CD
```
```{code-cell} ipython3
:tags: [hide-cell]
```{code-cell}
:tags: ['hide-cell']
print('numpy+numba+dask')
print('numpy+dask array:')
def mvb(M,v):
return (M * v[None, :]).sum(axis=1)
resn = mvb(CD,x).compute()
%timeit mvb(CD,x).compute()
print(np.linalg.norm(resn - trs))
```
```{code-cell} ipython3
print('numpy+dask map')
@nu.njit('float64[:](float64[:,:],float64[:])')
def mvb(M,v):
return (M * np.expand_dims(v, 0)).sum(axis=1)
# drop_axis ist nötig, damit das Format der Ausgabe bekannt ist und map_blocks sich entsprechend
# verhalten kann
resd = da.map_blocks(mvb,CD,x, drop_axis=1).compute()
%timeit da.map_blocks(mvb,CD,x, drop_axis=1).compute()
print(np.linalg.norm(resd - trs))
```
```{code-cell}
:tags: ['hide-cell']
# eine zusätzliche Variante
```{code-cell} ipython3
:tags: [hide-cell]
# eine zusätzliche Variante mit dask delayed (neu)
# die geeignet ist für Fälle wo dask.array nicht ausreicht die Kalkulation geeignet zu beschreiben.
# Hinweis: dask optimiert die Operationen intern
def mvb(M,v):
return (M * np.expand_dims(v, 0)).sum(axis=1)
print('numpy+dask delayed')
from dask import delayed
resd = delayed((CD * x[None, :]).sum(axis=1)).compute()
%timeit delayed((CD * x[None, :]).sum(axis=1)).compute()
resd = delayed(mvb(CD, x)).compute()
%timeit delayed(mvb(CD, x)).compute()
print(np.linalg.norm(resd - trs))
```
```{code-cell}
:tags: ['hide-cell']
# Hiermit wird das sehr viel langsamer, da durch den Client processes laufen, die alle den Speicher kopiert bekommen müssen.
```{code-cell} ipython3
:tags: [hide-cell]
# Hiermit wird das sehr viel langsamer, da durch den Client processes laufen, die alle den Speicher
# kopiert bekommen müssen. aber wir können beobachten wie die Berechnung vor sich geht,
# was entsprechend interessant ist
from dask.distributed import Client
c= Client()
c
```
```{code-cell} ipython3
:tags: [hide-cell]
# Führen wir das aus, kann man sehen, dass bei der Parallelisierung sehr lange die CPU nichts tut.
# Es ist anzunehmen das der Overhead durch die Speicherzugriffe zu gross ist. (Die CPU wartet auf den Speicher)
from imageio import imread
import holoviews as hv
hv.extension('matplotlib')
hv.RGB(np.asarray(imread("../../data/exercises/exercise_dashboard.png")))
```
......@@ -3,8 +3,10 @@ jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.10.3
kernelspec:
display_name: Python 3
display_name: Python 3 (ipykernel)
language: python
name: python3
---
......@@ -16,14 +18,14 @@ kernelspec:
Mal wieder Mandelbrot als Beispiel :) Hier wollen wir Interaktivität auf ein neues
Niveau heben und es uns dennoch einfach machen, dies umzusetzen.
```{code-cell}
```{code-cell} ipython3
import numpy as np
import holoviews as hv
from numba import njit
hv.extension('bokeh')
```
```{code-cell}
```{code-cell} ipython3
HEIGHT=500
WIDTH=500
......@@ -49,7 +51,7 @@ def create_fractal(min_x, max_x, min_y, max_y, max_iters):
image[y, x] = mandel(real, imag, max_iters)
return image
def get_fractal(x_range, y_range, max_iters):
def get_fractal(x_range, y_range, max_iters=10):
min_x, max_x = x_range
min_y, max_y = y_range
return hv.Image(create_fractal(min_x, max_x, -max_y, -min_y, max_iters),
......@@ -70,7 +72,6 @@ options = {'Histogram': dict(framewise=True, logy=True, width=150),
.redim.values(max_iters=range(25, 501, 25))
.options(options)
)
```
(streams)=
......@@ -93,10 +94,9 @@ hv.streams.Stream.define(name, kwargs)
die wir dann instanzieren:
```{code-cell}
```{code-cell} ipython3
xyrange_class = hv.streams.Stream.define('XYrange', x_range=(-1,1), y_range=(-1,1))
xyrange = xyrange_class()
```
Das Verknüpfen mit der DynamicMap geschieht über die Option `streams` und enthält eine Liste von
......@@ -108,7 +108,7 @@ hv.DynamicMap(streams=[liste])
Unser Ausgangsbeispiel mit diesem selbst erstellten einfachen Stream:
```{code-cell}
```{code-cell} ipython3
options = {'Image': dict(cmap='fire', logz=True, height=HEIGHT, width=WIDTH, xaxis=None, yaxis=None)}
dmap = (hv.DynamicMap(get_fractal,
label='Manderbrot Explorer',
......@@ -122,8 +122,9 @@ dmap
Wir können nun Werte in dem Stream ändern mittels der DynamicMap-Methode `.event()`:
```{code-cell}
dmap.event(x_range=(-0.5,0.5), y_range=(-1,0.5))
```{code-cell} ipython3
dmap.event(x_range=(-1.,0.5), y_range=(-0.2,0.5))
dmap
```
Auf diese Weise haben wir eine bestehende Grafik, verbunden mit einem Objekt verschiedener Eigenschaften.
......@@ -139,7 +140,7 @@ Häufig koppeln wir sie aber mit einer *DynamicMap*: Über die DynamicMap wird d
Eine Liste dieser Bausteine erhält mit folgender Code-Zelle:
```{code-cell}
```{code-cell} ipython3
import param
listing = ', '.join(sorted([str(s.name) for s in param.descendents(hv.streams.LinkedStream)]))
print('The linked stream classes supported by HoloViews are:\n\n{listing}'.format(listing=listing))
......@@ -156,7 +157,7 @@ hv.streams.RangeXY(x_range=, y_range=)
Damit können wir dann bereits das Ausgangs-Beispiel vollständig verstehen und einen RangeXY
stream benutzen, der dann mit der DynamicMap verbunden wird, die das Fraktal berechnet.
```{code-cell}
```{code-cell} ipython3
range_stream = hv.streams.RangeXY(x_range=(-1, 1), y_range=(-1, 1))
options = {'Histogram': dict(framewise=True, logy=True, width=150),
......@@ -187,8 +188,9 @@ hv.streams.Tap(source=daten/plot, x=startx, y=starty)
Den Datensatz wieder laden und die Darstellung machen, die wir bereits hatten:
```{code-cell}
:tags: ['remove-cell']
```{code-cell} ipython3
:tags: [remove-cell]
import requests
import io
......@@ -198,9 +200,13 @@ with open("temperature_reset.hdf", mode='wb') as file:
file.write(response.content)
```
```{code-cell}
```{code-cell} ipython3
import pandas as pd
temperatureframe = pd.read_hdf("temperature_reset.hdf", key='myIdentifier')
temperatureframe
```
```{code-cell} ipython3
year_average = temperatureframe.groupby(['latitude', 'longitude']).mean()
yearavplot = hv.HeatMap(year_average, kdims=['longitude', 'latitude'], vdims = ['tem']).options(height=500,width=800)
yearavplot
......@@ -209,32 +215,47 @@ yearavplot
Dann erzeugen wir den tap-stream abhängig von `yearavplot`; der HeatMap mit den mittleren
Temperaturdaten.
```{code-cell}
```{code-cell} ipython3
posxy = hv.streams.Tap(source=yearavplot, x=1, y=1)
```
Wir wollen damit eine DynamicMap erzeugen, die mit der Information der Koordinaten eine
Curve über die Monate des Jahres des jeweiligen Punktes angibt. Dazu schauen wir uns kurz an,
Curve über die Monate des Jahres des jeweiligen Punktes angibt. Dazu schauen wir uns an,
wie wir diese Daten aus dem Datenframe holen können:
```{code-cell}
temperatureframe.loc[(temperatureframe['latitude'] == 87.5) & (temperatureframe['longitude'] == -177.5)].head()
```{code-cell} ipython3
temperatureframe.loc[
(temperatureframe['latitude'] == 87.5) &
(temperatureframe['longitude'] == -177.5)]
```
Dann die Funktion schreiben für die DynamicMap und dieselbe erzeugen:
```{code-cell}
```{code-cell} ipython3
def tap_curve(x, y):
return hv.Curve(temperatureframe['tem'].loc[(temperatureframe['longitude'] == float(x)) & (temperatureframe['latitude'] == float(y))], kdims='time', label=f'Longitude: {x}, Latitude: {y}')
# finde den nächsten punkt vom tap-input ausgehend. Leider ist dieser nicht exakt, sondern
# enthält ungenaue werte.
ulon_i = temperatureframe['longitude'].unique()
ulat_i = temperatureframe['latitude'].unique()
idx, idy = np.argmin((x-ulon_i)**2), np.argmin((y-ulat_i)**2)
cd = temperatureframe['tem'].loc[(temperatureframe['longitude'] == ulon_i[idx]) &
(temperatureframe['latitude'] == ulat_i[idy])]
return hv.Curve(cd, kdims=['time'], vdims=['tem'], label=f'Longitude: {x}, Latitude: {y}')
```
```{code-cell} ipython3
tap_dmap = hv.DynamicMap(tap_curve, streams=[posxy])
```
... und dann die HeatMap und die DynamicMap nebeneinander darstellen:
```{code-cell}
```{code-cell} ipython3
options = {'Curve': dict(framewise=True, height=400, width=375, yaxis='right'),
'HeatMap': dict(fontsize={'xticks': '6pt'}, height=400,
tools=['hover'], width=600, xrotation=90)}
(yearavplot + tap_dmap).options(options)
```
```{code-cell} ipython3
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment