Wenn Sie versuchen, meteorologische Daten über einen langen Zeitraum auf verschiedenen Druckebenen zu zeichnen, nimmt die Verschachtelung für Anweisungen und das Lesen von netCDF-Dateien natürlich zu.
Daher habe ich untersucht, wie sich die zum Abrufen eines Datenarrays erforderliche Zeit ändert, indem die Verschachtelungsstruktur der for-Anweisung geändert wird.
Für den Bestätigungscode habe ich auf [hier] verwiesen (https://note.nkmk.me/python-timeit-measure/). Die Daten wurden von NCAR's RDA erhalten. Die Daten sind ein Geopotential, eine vierdimensionale Anordnung von [Zeit, Druckebene, Breite, Länge]. Die Zeit beträgt 24 Stunden von 0 bis 23 und das Druckniveau beträgt 37.
func_1
liest die Daten einmal und speichert das dreidimensionale Array in a. Danach wird b durch das Geopotential in jeder Druckebene ersetzt.
func_2
liest die Daten für jede Druckebene und erhält jedes Mal ein zweidimensionales Array.
check1.py
import timeit
from netCDF4 import Dataset
def func_1():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
a = nc.variables['Z'][0, :]
for i in range(len(a)):
b = a[i, :]
return 0
def func_2():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
lev = nc.variables['level'][:]
for i in range(len(lev)):
b = nc.variables['Z'][0, i, :]
return 0
loop = 20
result_1 = timeit.timeit(lambda: func_1(), number=loop)
result_2 = timeit.timeit(lambda: func_2(), number=loop)
print('1: ', result_1 / loop)
print('2: ', result_2 / loop)
Ergebnis ist
1: 0.009774951753206551
2: 0.018051519710570573
Es wurde wie. Es gibt einen doppelten Geschwindigkeitsunterschied. Daraus wurde festgestellt, dass die Geschwindigkeit des Lesens des dreidimensionalen Arrays der Geschwindigkeit des Lesens des dreidimensionalen Arrays zu einem Zeitpunkt und der Geschwindigkeit des Lesens des zweidimensionalen Arrays jedes Mal überlegen ist.
Da es sich bei den Daten, die Sie verarbeiten möchten, um ein 4-dimensionales Array handelt, überprüfen Sie auch den Fall eines 4-dimensionalen Arrays. Wie beim Bestätigungscode 1 werden "func_1" und "func_2" einmal von "func_1" und jedes Mal von "func_2" gelesen.
check1.py
import timeit
from netCDF4 import Dataset
def func_1():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
a = nc.variables['Z'][0, :]
for i in range(len(a)):
b = a[i, :]
return 0
def func_2():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
lev = nc.variables['level'][:]
for i in range(len(lev)):
b = nc.variables['Z'][0, i, :]
return 0
loop = 10
result_1 = timeit.timeit(lambda: func_1(), number=loop)
result_2 = timeit.timeit(lambda: func_2(), number=loop)
print('1: ', result_1 / loop)
print('2: ', result_2 / loop)
Dann war das Ergebnis wie folgt.
1: 1.4546271565370261
2: 1.3412013622000813
Es stellte sich heraus, dass die Methode zum sofortigen Lesen eines Arrays, die in 3D schnell war, langsamer ist als die Methode zum Lesen jedes Mal in 4D. Bedeutet das, dass die Verarbeitungsgeschwindigkeit langsamer ist als die for-Anweisung, wenn das Array mehrdimensional wird? Es ist ein interessantes Ergebnis. Von nun an dachte ich auch, wenn ich das Beste aus beiden Welten nehmen würde, wäre es ein Programm, das Daten am schnellsten lesen könnte, also verglich ich die Geschwindigkeit des folgenden Codes.
Ich habe eine neue func_3
erstellt und die Geschwindigkeit verglichen. func_3
ist eine Funktion, die die Zeit mit einer for-Anweisung dreht und jedes Mal ein dreidimensionales Array [Druckebene, Breite, Länge] liest.
check3.py
from netCDF4 import Dataset
import timeit
def func_1():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
a = nc.variables['Z'][:]
for i in range(len(a)):
b = a[i, :]
for j in range(len(b)):
c = b[j, :]
return 0
def func_2():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
time = nc.variables['time'][:]
lev = nc.variables['level'][:]
for j in range(len(time)):
for i in range(len(lev)):
b = nc.variables['Z'][j, i, :]
return 0
def func_3():
nc = Dataset('../data/era5/Z_2020070100_2020070123.nc', 'r')
time = nc.variables['time'][:]
for j in range(len(time)):
a = nc.variables['Z'][j, :]
for i in range(len(a)):
b = a[i, :]
return 0
loop = 10
result_1 = timeit.timeit(lambda: func_1(), number=loop)
result_2 = timeit.timeit(lambda: func_2(), number=loop)
result_3 = timeit.timeit(lambda: func_3(), number=loop)
print('1: ', result_1 / loop)
print('2: ', result_2 / loop)
print('3: ', result_3 / loop)
Das Ergebnis ist wie folgt.
1: 1.4101094176992774
2: 1.344068780587986
3: 1.0753227178938687
Wie zu erwarten war, war func_3
am schnellsten.
Was wir aus den drei Überprüfungen gelernt haben
Das ist was es bedeutet. Die Visualisierung meteorologischer Daten ist eine zeitaufwändige Aufgabe. Wir hoffen, dass Sie durch diese Überprüfung Zeit sparen.