Короткий ответ заключается в том, что преобразование набора данных в 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