Рассчитать Root Квадратная ошибка набора данных xarray - PullRequest
2 голосов
/ 22 марта 2020

У меня есть набор данных xarray month_data за январь со следующей информацией:

lat: float64 (192)
lon: float64 (288)
time: object (1200)(monthly data)

Data Variables:
tas: (time, lat, lon)[[[45,78,...],...]...]

У меня есть значение истинной земли grnd_trth , которое имеет истинные данные января

Coordinates:
lat: float64 (192)
lon: float64 (288)

Data Variables:
tas(lat and lon)

Теперь я хочу вычислить root квадратичную ошибку для каждого месяца из month_data относительно grnd_trth , я попытался использовать циклы, и я думаю, что это работает нормально, вот моя попытка:

rms = []

for i in range(1200):
  err = 0
  for j in (grnd_trth.tas[0] - monthly_data.tas[i]).values:
    for k in j:
      err += k**2
  rms.append(err**1/2)

Я просто хочу знать, есть ли более эффективный способ или какая-либо прямая функция для этого?

Редактировать:

Вывод month_data.tas :

xarray.Datarray 'tas': (time:1200 lat: 192 lon: 288)
array([[[45,46,45,4....],....]...]

Coordinates:
lat:
array([-90. , -89.75,...])

lon:
array([0., 1.25.,.... ])

time:
array([cftime.DatetimeNoLeap(0001-01-15 12:00:00),
       cftime.DatetimeNoLeap(0002-01-15 12:00:00),
       cftime.DatetimeNoLeap(0003-01-15 12:00:00), ...,
       cftime.DatetimeNoLeap(1198-01-15 12:00:00),
       cftime.DatetimeNoLeap(1199-01-15 12:00:00),
       cftime.DatetimeNoLeap(1200-01-15 12:00:00)]

Вывод grnd_trth.tas :

xarray.Datarray 'tas': (lat: 192 lon: 288)
array([[45,46,45,4....],....]

Coordinates:
lat:
array([-90. , -89.75,...])

lon:
array([0., 1.25.,.... ])

time:
array([cftime.DatetimeNoLeap(0001-01-15 12:00:00)]

Но когда я просто использую функцию .values ​​(), она возвращает мне только массив значений!

1 Ответ

1 голос
/ 23 марта 2020

С точки зрения более эффективной работы, есть две вещи, на которые следует обратить внимание.

1) Вы можете выполнять арифметические c операции непосредственно над объектами xarray, например.

for time_idx in range(1200):
    # For each time idx, find the root squared error at 
    # each pixel between grnd_truth and monthly_data

    err2 = (grnd_truth.tas - monthly_data.tas[time_idx,...])**2
    err  = err2**(1/2)

2) Есть вызов метода .sum(), который суммирует все элементы в массив, так что это означает, что вам не нужно будет делать строку for k in j: для суммирования по пикселям. Например,

rms=[]

for time_idx in range(2000):
    # same two lines as before...

    # sum over every pixel and extract the value from the DataArray
    err_tot = err.sum().values

    # Add to running total
    rms.append(err_tot)

Теперь следует отметить, что, просто извлекая значения из DataArray, вы теряете все метаданные о массиве! Так что это на самом деле не лучшая практика, но сейчас я думаю, что это отвечает на ваш вопрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...