Python xarray波周期(以秒为单位)作为timedelta64摄取

Python xarray波周期(以秒为单位)作为timedelta64摄取,python,netcdf,python-xarray,opendap,Python,Netcdf,Python Xarray,Opendap,测量海浪周期的变量的“单位”属性以“秒”为单位。这不是datetime字段,但xarray会自动将此变量作为timedelta64接受。由于单位不是“秒自…”,我会假设xarray应该将其视为一个普通的float32数据数组,但显然不是这样。我有没有办法告诉xarray将波浪周期变量作为float32接收,或者在接收后将它们从timedelta64转换回原始值?我仍然希望它将“time”变量转换为timedelta64,因此我不想关闭整个数据集的转换,只针对特定变量(Tper、sper、wper

测量海浪周期的变量的“单位”属性以“秒”为单位。这不是datetime字段,但xarray会自动将此变量作为timedelta64接受。由于单位不是“秒自…”,我会假设xarray应该将其视为一个普通的float32数据数组,但显然不是这样。我有没有办法告诉xarray将波浪周期变量作为float32接收,或者在接收后将它们从timedelta64转换回原始值?我仍然希望它将“time”变量转换为timedelta64,因此我不想关闭整个数据集的转换,只针对特定变量(Tper、sper、wper)

以下是我在TDS服务器中使用的wave forecast的基本OPeNDAP URL:

建议?谢谢

您可以在此处使用OPeNDAP页面查看类似“ncdump”的输出:

或者您可以在OPeNDAP URL上运行ncdump,如下所示:

ncdump-h

其结果如下:

netcdf WaveWatch_III_Hawaii_Regional_Wave_Model_best {
dimensions:
        lat = 101 ;
        lon = 141 ;
        time = 54453 ;
        z = 1 ;
variables:
        float lon(lon) ;
                lon:units = "degrees_east" ;
                lon:long_name = "longitude" ;
                lon:standard_name = "longitude" ;
                lon:short_name = "lon" ;
                lon:axis = "x" ;
                lon:_CoordinateAxisType = "Lon" ;
        float lat(lat) ;
                lat:units = "degrees_north" ;
                lat:long_name = "latitude" ;
                lat:standard_name = "latitude" ;
                lat:short_name = "lat" ;
                lat:axis = "y" ;
                lat:_CoordinateAxisType = "Lat" ;
        float z(z) ;
                z:units = "meters" ;
                z:long_name = "depth below mean sea level" ;
                z:standard_name = "depth" ;
                z:short_name = "depth" ;
                z:axis = "z" ;
                z:_CoordinateAxisType = "Height" ;
        double time(time) ;
                time:long_name = "Forecast time for ForecastModelRunCollection" ;
                time:standard_name = "time" ;
                time:calendar = "proleptic_gregorian" ;
                time:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time:missing_value = NaN ;
                time:_CoordinateAxisType = "Time" ;
        double time_run(time) ;
                time_run:long_name = "run times for coordinate = time" ;
                time_run:standard_name = "forecast_reference_time" ;
                time_run:calendar = "proleptic_gregorian" ;
                time_run:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time_run:missing_value = NaN ;
                time_run:_CoordinateAxisType = "RunTime" ;
        double time_offset(time) ;
                time_offset:long_name = "offset hour from start of run for coordinate = time" ;
                time_offset:standard_name = "forecast_period" ;
                time_offset:calendar = "proleptic_gregorian" ;
                time_offset:units = "hours since 2011-06-21T00:00:00Z" ;
                time_offset:missing_value = NaN ;
        float Thgt(time, z, lat, lon) ;
                Thgt:units = "meters" ;
                Thgt:long_name = "significant wave height" ;
                Thgt:standard_name = "sea_surface_wave_significant_height" ;
                Thgt:short_name = "Thgt" ;
                Thgt:valid_range = 0.f, 60.f ;
                Thgt:_FillValue = NaNf ;
                Thgt:coordinates = "time_run time z lat lon " ;
        float Tper(time, z, lat, lon) ;
                Tper:units = "seconds" ;
                Tper:long_name = "peak wave period" ;
                Tper:standard_name = "sea_surface_wave_period_at_variance_spectral_density_maximum" ;
                Tper:short_name = "Tper" ;
                Tper:valid_range = 0.f, 60.f ;
                Tper:_FillValue = NaNf ;
                Tper:coordinates = "time_run time z lat lon " ;
        float Tdir(time, z, lat, lon) ;
                Tdir:units = "degrees" ;
                Tdir:long_name = "peak wave direction" ;
                Tdir:standard_name = "sea_surface_wave_from_direction" ;
                Tdir:short_name = "Tdir" ;
                Tdir:valid_range = 0.f, 360.f ;
                Tdir:_FillValue = NaNf ;
                Tdir:coordinates = "time_run time z lat lon " ;
        float shgt(time, z, lat, lon) ;
                shgt:units = "meters" ;
                shgt:long_name = "swell significant wave height" ;
                shgt:standard_name = "sea_surface_swell_wave_significant_height" ;
                shgt:short_name = "shgt" ;
                shgt:valid_range = 0.f, 60.f ;
                shgt:_FillValue = NaNf ;
                shgt:coordinates = "time_run time z lat lon " ;
        float sper(time, z, lat, lon) ;
                sper:units = "seconds" ;
                sper:long_name = "swell peak wave period" ;
                sper:standard_name = "sea_surface_swell_wave_period" ;
                sper:short_name = "sper" ;
                sper:valid_range = 0.f, 60.f ;
                sper:_FillValue = NaNf ;
                sper:coordinates = "time_run time z lat lon " ;
        float sdir(time, z, lat, lon) ;
                sdir:units = "degrees" ;
                sdir:long_name = "swell peak wave direction" ;
                sdir:standard_name = "sea_surface_swell_wave_from_direction" ;
                sdir:short_name = "sdir" ;
                sdir:valid_range = 0.f, 360.f ;
                sdir:_FillValue = NaNf ;
                sdir:coordinates = "time_run time z lat lon " ;
        float whgt(time, z, lat, lon) ;
                whgt:units = "meters" ;
                whgt:long_name = "wind significant wave height" ;
                whgt:standard_name = "sea_surface_wind_wave_significant_height" ;
                whgt:short_name = "whgt" ;
                whgt:valid_range = 0.f, 60.f ;
                whgt:_FillValue = NaNf ;
                whgt:coordinates = "time_run time z lat lon " ;
        float wper(time, z, lat, lon) ;
                wper:units = "seconds" ;
                wper:long_name = "wind peak wave period" ;
                wper:standard_name = "sea_surface_wind_wave_period" ;
                wper:short_name = "wper" ;
                wper:valid_range = 0.f, 60.f ;
                wper:_FillValue = NaNf ;
                wper:coordinates = "time_run time z lat lon " ;
        float wdir(time, z, lat, lon) ;
                wdir:units = "degrees" ;
                wdir:long_name = "wind peak wave direction" ;
                wdir:standard_name = "sea_surface_wind_wave_from_direction" ;
                wdir:short_name = "wdir" ;
                wdir:valid_range = 0.f, 360.f ;
                wdir:_FillValue = NaNf ;
                wdir:coordinates = "time_run time z lat lon " ;

// global attributes:
                :title = "WaveWatch III (WW3) Hawaii Regional Wave Model" ;
                :_CoordSysBuilder = "ucar.nc2.dataset.conv.CF1Convention" ;
                :Conventions = "CF-1.6, ACDD-1.3" ;
                :cdm_data_type = "Grid" ;
                :featureType = "GRID" ;
                :location = "Proto fmrc:WaveWatch_III_Hawaii_Regional_Wave_Model" ;
                :id = "ww3_hawaii" ;
                :naming_authority = "org.pacioos" ;
                :Metadata_Link = "http://pacioos.org/metadata/ww3_hawaii.html" ;
                :ISO_Topic_Categories = "oceans" ;
                :summary = "Through a collaborative effort with NOAA/NCEP and NWS Honolulu, the University of Hawaii has implemented a global-scale WaveWatch III (WW3) model, which in turn provides boundary conditions for this Hawaii regional WW3: a 7-day model with a 5-day hourly forecast at approximately 5-km or 0.05-deg resolution. The primary purpose of this regional model is to capture island effects such as island shadowing, refraction, and accurate modeling of local wind waves. Hawaii WW3 is forced with winds from the University of Hawaii Meteorology Department\'s operational mesoscale model, which has a more suitable spatial resolution than the global scale wind field. The Hawaii regional WW3 also provides boundary conditions for nearshore island-scale models via Simulating WAves Nearshore (SWAN). While considerable effort has been made to implement all model components in a thorough, correct, and accurate manner, numerous sources of error are possible. As such, please use these data with the caution appropriate for any ocean related activity." ;
                :keywords = "Earth Science Services > Models > Ocean General Circulation Models (OGCM)/Regional Ocean Models, Earth Science Services > Models > Weather Research/Forecast Models, Earth Science > Oceans > Ocean Waves > Significant Wave Height, Earth Science > Oceans > Ocean Waves > Wave Period, Earth Science > Oceans > Ocean Waves > Wave Speed/Direction" ;
                :keywords_vocabulary = "GCMD Science Keywords" ;
                :platform = "Models/Analyses > > Operational Models" ;
                :platform_vocabulary = "GCMD Platform Keywords" ;
                :instrument = "Not Applicable > Not Applicable" ;
                :instrument_vocabulary = "GCMD Instrument Keywords" ;
                :locations = "Continent > North America > United States Of America > Hawaii, Ocean > Pacific Ocean > Central Pacific Ocean > Hawaiian Islands" ;
                :locations_vocabulary = "GCMD Location Keywords" ;
                :standard_name_vocabulary = "CF Standard Name Table v39" ;
                :comment = "Model runs produced by Dr. Kwok Fai Cheung (cheung@hawaii.edu)." ;
                :geospatial_lat_min = 18. ;
                :geospatial_lat_max = 23. ;
                :geospatial_lon_min = 199. ;
                :geospatial_lon_max = 206. ;
                :geospatial_vertical_min = 0. ;
                :geospatial_vertical_max = 0. ;
                :geospatial_bounds = "POLYGON ((18 -161.0, 23 -161.0, 23 -154.0, 18 -154.0, 18 -161.0))" ;
                :geospatial_bounds_crs = "EPSG:4326" ;
                :time_coverage_start = "2011-06-21T21:00:00Z" ;
                :geospatial_lat_units = "degrees_north" ;
                :geospatial_lat_resolution = 0.05 ;
                :geospatial_lon_units = "degrees_east" ;
                :geospatial_lon_resolution = 0.05 ;
                :geospatial_vertical_units = "meters" ;
                :geospatial_vertical_positive = "up" ;
                :geospatial_vertical_resolution = 0. ;
                :time_coverage_resolution = "PT1H" ;
                :creator_email = "cheung@hawaii.edu" ;
                :creator_name = "Kwok Fai Cheung" ;
                :creator_type = "person" ;
                :creator_url = "http://www.ore.hawaii.edu/OE/cheung_research.htm" ;
                :creator_institution = "University of Hawaii" ;
                :date_created = "2011-06-22" ;
                :date_issued = "2011-06-22" ;
                :date_modified = "2014-06-23" ;
                :date_metadata_modified = "2017-01-30" ;
                :institution = "University of Hawaii" ;
                :project = "Pacific Islands Ocean Observing System (PacIOOS)" ;
                :program = "Pacific Islands Ocean Observing System (PacIOOS)" ;
                :contributor_name = "Jim Potemra" ;
                :contributor_role = "distributor" ;
                :publisher_email = "info@pacioos.org" ;
                :publisher_name = "Pacific Islands Ocean Observing System (PacIOOS)" ;
                :publisher_url = "http://pacioos.org" ;
                :publisher_institution = "University of Hawaii" ;
                :publisher_type = "group" ;
                :license = "The data may be used and redistributed for free but is not intended for legal use, since it may contain inaccuracies. Neither the data Contributor, University of Hawaii, PacIOOS, NOAA, State of Hawaii nor the United States Government, nor any of their employees or contractors, makes any warranty, express or implied, including warranties of merchantability and fitness for a particular purpose, or assumes any legal liability for the accuracy, completeness, or usefulness, of this information." ;
                :acknowledgement = "The Pacific Islands Ocean Observing System (PacIOOS) is funded through the National Oceanic and Atmospheric Administration (NOAA) as a Regional Association within the U.S. Integrated Ocean Observing System (IOOS). PacIOOS is coordinated by the University of Hawaii School of Ocean and Earth Science and Technology (SOEST)." ;
                :source = "WaveWatch III (WW3) numerical wave model" ;
                :references = "http://pacioos.org/waves/model-hawaii/, http://polar.ncep.noaa.gov/waves/wavewatch/" ;
                :history = "FMRC Best Dataset" ;

如果可能的话,您介意显示
ncdump-h file.nc
的输出吗

我快速查看了WaveWatchIII实验中的一些海浪周期数据,一切看起来都很好

ncdump -h ww3.20140101_20141231.nc
netcdf ww3.20140101_20141231 {
dimensions:
    longitude = 46 ;
    latitude = 17 ;
    time = UNLIMITED ; // (365 currently)
variables:
    float longitude(longitude) ;
            longitude:units = "degree_east" ;
            longitude:long_name = "longitude" ;
            longitude:standard_name = "longitude" ;
            longitude:valid_min = -180.f ;
            longitude:valid_max = 180.f ;
            longitude:axis = "X" ;
    float latitude(latitude) ;
            latitude:units = "degree_north" ;
            latitude:long_name = "latitude" ;
            latitude:standard_name = "latitude" ;
            latitude:valid_min = -90.f ;
            latitude:valid_max = 90.f ;
            latitude:axis = "Y" ;
    double time(time) ;
            time:long_name = "julian day (UT)" ;
            time:standard_name = "time" ;
            time:units = "days since 1850-01-01T00:00:00Z" ;
            time:conventions = "relative julian days with decimal part (as parts of the day )" ;
            time:axis = "T" ;
...
    short t01(time, latitude, longitude) ;
            t01:long_name = "mean period T01" ;
            t01:standard_name = "sea_surface_wind_wave_mean_period_from_variance_spectral_density_first_frequency_moment" ;
            t01:globwave_name = "mean_period_t01" ;
            t01:units = "s" ;
            t01:_FillValue = -32767s ;
            t01:scale_factor = 0.01f ;
            t01:add_offset = 0.f ;
            t01:valid_min = 0 ;
            t01:valid_max = 5000 ;

S:开始日期;M:团员;X:lon;Y:lat;L:交付周期

>>> ts = remote_data['ts'][0, 0, -1, 45, 80]
>>> ts
<xarray.DataArray 'ts' ()>
array(281.383544921875)
Coordinates:
    S        datetime64[ns] 2017-10-01
    M        float32 1.0
    X        float32 80.0
    L        timedelta64[ns] 12:00:00
    Y        float32 -45.0
Attributes:
    pointwidth:     0.0
    standard_name:  surface_temperature
    long_name:      Surface Temperature
    level_type:     surface
    units:          Kelvin_scale
    cell_method:    time: mean

默认情况下,xarray将格式为“秒”的
units
属性的变量转换为
np.timedelta64
,并将格式为“秒自…”的变量转换为
np.datetime64

这对于某些应用来说很方便。为了使这更具体,让我突出显示netCDF文件中
ncdump-h
中的一部分:

netcdf WaveWatch_III_Hawaii_Regional_Wave_Model_best {
variables:
        double time(time) ;
                time:long_name = "Forecast time for ForecastModelRunCollection" ;
                time:standard_name = "time" ;
                time:calendar = "proleptic_gregorian" ;
                time:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time:missing_value = NaN ;
                time:_CoordinateAxisType = "Time" ;
        double time_run(time) ;
                time_run:long_name = "run times for coordinate = time" ;
                time_run:standard_name = "forecast_reference_time" ;
                time_run:calendar = "proleptic_gregorian" ;
                time_run:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time_run:missing_value = NaN ;
                time_run:_CoordinateAxisType = "RunTime" ;
        double time_offset(time) ;
                time_offset:long_name = "offset hour from start of run for coordinate = time" ;
                time_offset:standard_name = "forecast_period" ;
                time_offset:calendar = "proleptic_gregorian" ;
                time_offset:units = "hours since 2011-06-21T00:00:00Z" ;
                time_offset:missing_value = NaN ;
        float Tper(time, z, lat, lon) ;
                Tper:units = "seconds" ;
                Tper:long_name = "peak wave period" ;
                Tper:standard_name = "sea_surface_wave_period_at_variance_spectral_density_maximum" ;
                Tper:short_name = "Tper" ;
                Tper:valid_range = 0.f, 60.f ;
                Tper:_FillValue = NaNf ;
                Tper:coordinates = "time_run time z lat lon " ;
我对CF的理解是,
forecast\u period
应该等于
time
forecast\u reference\u time
之间的差值,即,
forecast\u period=time-forecast\u reference\u time
。如果您使用“小时”形式的单位指定了
time\u offset
变量,那么它将被解码为
timedelta64
,以及
time
time\u run
datetime64
,因此xarray的算法实际上会满足此标识。如果您只想包含其中的两个变量,并想动态计算第三个变量,那么您可能会发现这很有用

另一方面,您可能不想将
Tper
变量转换为
timedelta64
。从技术上讲,它也是一个时间段,但与时间相比,它不是一个有意义的变量

不幸的是,xarray目前无法通过查看变量元数据来区分这两种情况,因此它将所有内容转换为
timedelta64
(尽管我很乐意讨论您在GitHub上的想法)。目前,最好的解决方法是在使用xarray解码之前从这些变量中删除units属性,例如

raw = xr.open_dataset(url, decode_cf=False)
del raw.Tper.attrs['units']
ds = xr.decode_cf(raw)

谢谢,雷。您的“t01”变量的单位为“s”,而我的“Tper”、“sper”和“wper”变量的单位为“秒”。这些应该是等价的,不重要。嗯,我还看到你的“t01”变量应用了比例因子和加法偏移量(以及有效最小值和有效最大值),所以我想知道这些属性是否会触发xarray,使其不将其视为日期时间字段???@johnmarer你可以使用as
ncate-O-a单位,Tper,O,c,“s”文件.nc来更改NetCDF文件的单位,看看它是否为“s”事实上,我现在通过TDS中的NcML实现了这一点,而不是“秒”造成了我们的差异。直觉是正确的。当我将“Tper”改为“s”而不是“seconds”时,这个波周期变量被视为浮点数组,而不是时间坐标。这似乎是xarray的一个疏忽(bug)。有趣的是,将其更改为“秒”(而不是复数“秒”)也会将数据作为浮点数组而不是时间坐标导入。因此,唯一令人震惊的条目是“秒”。谢谢你帮助我找到解决办法。不用担心。可能想在github上提出一个正式问题其他人(包括我)将来可能会遇到这个问题好的,谢谢。现在完成:
>>> T = ts.coords['S'].values + ts.coords['L'].values
>>> T
numpy.datetime64('2017-10-01T12:00:00.000000000')
netcdf WaveWatch_III_Hawaii_Regional_Wave_Model_best {
variables:
        double time(time) ;
                time:long_name = "Forecast time for ForecastModelRunCollection" ;
                time:standard_name = "time" ;
                time:calendar = "proleptic_gregorian" ;
                time:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time:missing_value = NaN ;
                time:_CoordinateAxisType = "Time" ;
        double time_run(time) ;
                time_run:long_name = "run times for coordinate = time" ;
                time_run:standard_name = "forecast_reference_time" ;
                time_run:calendar = "proleptic_gregorian" ;
                time_run:units = "hours since 2011-06-21 00:00:00.000 UTC" ;
                time_run:missing_value = NaN ;
                time_run:_CoordinateAxisType = "RunTime" ;
        double time_offset(time) ;
                time_offset:long_name = "offset hour from start of run for coordinate = time" ;
                time_offset:standard_name = "forecast_period" ;
                time_offset:calendar = "proleptic_gregorian" ;
                time_offset:units = "hours since 2011-06-21T00:00:00Z" ;
                time_offset:missing_value = NaN ;
        float Tper(time, z, lat, lon) ;
                Tper:units = "seconds" ;
                Tper:long_name = "peak wave period" ;
                Tper:standard_name = "sea_surface_wave_period_at_variance_spectral_density_maximum" ;
                Tper:short_name = "Tper" ;
                Tper:valid_range = 0.f, 60.f ;
                Tper:_FillValue = NaNf ;
                Tper:coordinates = "time_run time z lat lon " ;
raw = xr.open_dataset(url, decode_cf=False)
del raw.Tper.attrs['units']
ds = xr.decode_cf(raw)