Python xarray удаляет координаты со всеми пропущенными переменными - PullRequest
0 голосов
/ 28 сентября 2018

Я импортирую разные файлы netCDF с помощью xarray, и в конце концов мне нужно конвертировать их все в один кадр данных panda.Это файл, содержащий данные о погоде, с множеством пропущенных наблюдений за определенными широтами и долготами во времени (потому что они находятся в середине океана).Координаты: Lat, Long, Time;Переменные: Temp, Pre.Прежде чем перейти к данным, я хочу избавиться от этих пропущенных наблюдений / целых координат.Есть ли простой и эффективный способ сделать это с помощью xarray?Я ничего не нашел в документах.

import pandas as pd 
import xarray as xr

path = 'Z:/Research/Climate_change/Climate_extreme_index/CRU data/'
temp_data = path+'cru_ts4.01.1901.2016.tmp.dat.nc'
pre_data = path+'cru_ts4.01.1901.2016.pre.dat.nc'

# Open netcdf 
def open_netcdf(datapath):
    print("Loading data...")
    data = xr.open_dataset(datapath, autoclose=True, drop_variables='stn', cache=True)
    return data
# Merge dataframes
data_temp = open_netcdf(temp_data)
data_pre = open_netcdf(pre_data)
all_data = xr.merge([data_temp, data_pre])

#################################################################
<xarray.Dataset>
Dimensions:  (lat: 360, lon: 720, time: 1392)
Coordinates:
  * lon      (lon) float32 -179.75 -179.25 -178.75 -178.25 -177.75 -177.25 ...
  * lat      (lat) float32 -89.75 -89.25 -88.75 -88.25 -87.75 -87.25 -86.75 ...
  * time     (time) datetime64[ns] 1901-01-16 1901-02-15 1901-03-16 ...
Data variables:
    tmp      (time, lat, lon) float32 ...
    pre      (time, lat, lon) float32 ...
#########################################################
#Dataframe example
                           tmp  pre
lat    lon     time                
-89.75 -179.75 1901-01-16  NaN  NaN
               1901-02-15  NaN  NaN
               1901-03-16  NaN  NaN
               1901-04-16  NaN  NaN
               1901-05-16  NaN  NaN
               1901-06-16  NaN  NaN
               1901-07-16  NaN  NaN
               1901-08-16  NaN  NaN
               1901-09-16  NaN  NaN
               1901-10-16  NaN  NaN
               1901-11-16  NaN  NaN

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Короткий ответ заключается в том, что преобразование набора данных в DataFrame перед отбрасыванием NaN является абсолютно правильным решением.

Одно из ключевых отличий между pandas DataFrame с MultiIndex и набором данных xarray состоит в том, что некоторые элементы индекса(комбинации времени / широты / долготы) можно отбрасывать в MultiIndex, не удаляя все экземпляры времени, широты или долготы с NaN.С другой стороны, DataArray моделирует каждое измерение (время, широта и долгота) как ортогональное, что означает, что NaN нельзя отбрасывать без удаления всего среза массива.Это основная особенность модели данных xarray.

В качестве примера, вот небольшой набор данных, который соответствует структуре ваших данных:

In [1]: import pandas as pd, numpy as np, xarray as xr

In [2]: ds = xr.Dataset({
   ...:     var: xr.DataArray(
   ...:         np.random.random((4, 3, 6)),
   ...:         dims=['time', 'lat', 'lon'],
   ...:         coords=[
   ...:             pd.date_range('2010-01-01', periods=4, freq='Q'),
   ...:             np.arange(-60, 90, 60),
   ...:             np.arange(-180, 180, 60)])
   ...:     for var in ['tmp', 'pre']})
   ...:

Мы можем создать поддельную маску земликоторый будет выводить определенные комбинации широты / долготы для каждого периода времени

In [3]: land_mask = (np.random.random((1, 3, 6)) > 0.3)

In [4]: ds = ds.where(land_mask)

In [5]: ds.tmp
Out[5]:
<xarray.DataArray 'tmp' (time: 4, lat: 3, lon: 6)>
array([[[0.020626, 0.937496,      nan, 0.052608, 0.266924, 0.361297],
        [0.299442, 0.524904, 0.447275, 0.277471,      nan, 0.595671],
        [0.541777, 0.279131,      nan, 0.282487,      nan,      nan]],

       [[0.473278, 0.302622,      nan, 0.664146, 0.401243, 0.949998],
        [0.225176, 0.601039, 0.543229, 0.144694,      nan, 0.196285],
        [0.059406, 0.37001 ,      nan, 0.867737,      nan,      nan]],

       [[0.571011, 0.864374,      nan, 0.123406, 0.663951, 0.684302],
        [0.867234, 0.823417, 0.351692, 0.46665 ,      nan, 0.215644],
        [0.425196, 0.777346,      nan, 0.332028,      nan,      nan]],

       [[0.916069, 0.54719 ,      nan, 0.11225 , 0.560431, 0.22632 ],
        [0.605043, 0.991989, 0.880175, 0.3623  ,      nan, 0.629986],
        [0.222462, 0.698494,      nan, 0.56983 ,      nan,      nan]]])
Coordinates:
  * time     (time) datetime64[ns] 2010-03-31 2010-06-30 2010-09-30 2010-12-31
  * lat      (lat) int64 -60 0 60
  * lon      (lon) int64 -180 -120 -60 0 60 120

Вы можете видеть, что ни один индекс широты или долготы не может быть отброшен без потери действительных данных.С другой стороны, когда данные преобразуются в DataFrame, измерения широты / долготы / времени накладываются друг на друга, то есть один элемент в этом индексе можно отбрасывать, не затрагивая другие строки:

In [6]: ds.to_dataframe()
Out[6]:
                          tmp       pre
lat lon  time
-60 -180 2010-03-31  0.020626  0.605749
         2010-06-30  0.473278  0.192560
         2010-09-30  0.571011  0.850161
         2010-12-31  0.916069  0.415747
    -120 2010-03-31  0.937496  0.465283
         2010-06-30  0.302622  0.492205
         2010-09-30  0.864374  0.461739
         2010-12-31  0.547190  0.755914
    -60  2010-03-31       NaN       NaN
         2010-06-30       NaN       NaN
         2010-09-30       NaN       NaN
         2010-12-31       NaN       NaN
     0   2010-03-31  0.052608  0.529258
         2010-06-30  0.664146  0.116303
         2010-09-30  0.123406  0.389693
...                       ...       ...
 60  120 2010-03-31       NaN       NaN
         2010-06-30       NaN       NaN
         2010-09-30       NaN       NaN
         2010-12-31       NaN       NaN

[72 rows x 2 columns]

Когда *На этом кадре данных вызывается 1016 *, данные не удаляются:

In [7]: ds.to_dataframe().dropna(how='all')
Out[7]:
                          tmp       pre
lat lon  time
-60 -180 2010-03-31  0.020626  0.605749
         2010-06-30  0.473278  0.192560
         2010-09-30  0.571011  0.850161
         2010-12-31  0.916069  0.415747
    -120 2010-03-31  0.937496  0.465283
         2010-06-30  0.302622  0.492205
         2010-09-30  0.864374  0.461739
         2010-12-31  0.547190  0.755914
     0   2010-03-31  0.052608  0.529258
         2010-06-30  0.664146  0.116303
         2010-09-30  0.123406  0.389693
         2010-12-31  0.112250  0.485259
     60  2010-03-31  0.266924  0.795056
         2010-06-30  0.401243  0.299577
         2010-09-30  0.663951  0.359567
         2010-12-31  0.560431  0.933291
...                       ...       ...
 60  0   2010-03-31  0.282487  0.148216
         2010-06-30  0.867737  0.643767
         2010-09-30  0.332028  0.471430
         2010-12-31  0.569830  0.380992
0 голосов
/ 29 сентября 2018

Существует функция dropna , например,

all_data.dropna('time', how='all')

Но на данный момент она реализована только для одного измерения одновременно, поэтому я не уверен, что она делает то, что выпожелает.Я так понимаю, ты хочешь удалить те пары широчайших и длинных пар, которые являются нанятыми на все времена?Я думаю, что вы должны повернуть широту, долготу в координаты мультииндекс панд и затем использовать дропну вдоль этого нового измерения.

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