如何读取 ecmwf 文件上的日期和时间
how to read date and time on ecmwf file
我在 netcdf 文件中有全球数据集。数据文件的时间信息为:
<type 'netCDF4._netCDF4.Variable'>
int32 time(time)
units: hours since 1900-01-01 00:00:0.0
long_name: time
calendar: gregorian
unlimited dimensions: time
current shape = (5875,)
filling off
当我从文件中提取时间时,我得到了这个数组:
array([ 876600, 876624, 876648, ..., 1017528, 1017552, 1017576], dtype=int32)
我的问题是如何将此数组转换为正确的日期格式?
[注意:这是每日数据集,数组中的数字对应于 1900-01-01 的一个小时]
你可以:
from datetime import date, timedelta
hours = [ 876600, 876624, 876648, 1017528, 1017552, 1017576]
base = date(1900, 1, 1)
for hour in hours:
base + timedelta(hours=hour)
2000-01-02
2000-01-03
2000-01-04
2016-01-30
2016-01-31
2016-02-01
如果您需要 hour
等信息,请使用 datetime
而不是 date
。
或使用 pd.DataFrame
:
df = pd.DataFrame(hours, columns=['hours'])
df['date'] = df.hours.apply(lambda x: base + timedelta(hours=x))
hours date
0 876600 2000-01-02
1 876624 2000-01-03
2 876648 2000-01-04
3 1017528 2016-01-30
4 1017552 2016-01-31
5 1017576 2016-02-01
使用 .apply
的解决方案效率极低,更不用说非惯用的和丑陋的了。 pandas 已经内置了进行时间增量转换的矢量化方法。
In [17]: hours = [ 876600, 876624, 876648, 1017528, 1017552, 1017576]*10000
In [18]: df = pd.DataFrame(hours, columns=['hours'])
In [19]: %timeit df.hours.apply(lambda x: base + timedelta(hours=x))
10 loops, best of 3: 74.2 ms per loop
In [21]: %timeit pd.to_timedelta(df.hours, unit='h') + Timestamp(base)
100 loops, best of 3: 11.3 ms per loop
In [23]: (pd.to_timedelta(df.hours, unit='h') + Timestamp(base)).head()
Out[23]:
0 2000-01-02
1 2000-01-03
2 2000-01-04
3 2016-01-30
4 2016-01-31
Name: hours, dtype: datetime64[ns]
执行此操作的理想方法是使用 netCDF4 num2date
import netCDF4
ncfile = netCDF4.Dataset('./foo.nc', 'r')
time = ncfile.variables['time']
dates = netCDF4.num2date(time[:], time.units, time.calendar)
我在 netcdf 文件中有全球数据集。数据文件的时间信息为:
<type 'netCDF4._netCDF4.Variable'>
int32 time(time)
units: hours since 1900-01-01 00:00:0.0
long_name: time
calendar: gregorian
unlimited dimensions: time
current shape = (5875,)
filling off
当我从文件中提取时间时,我得到了这个数组:
array([ 876600, 876624, 876648, ..., 1017528, 1017552, 1017576], dtype=int32)
我的问题是如何将此数组转换为正确的日期格式? [注意:这是每日数据集,数组中的数字对应于 1900-01-01 的一个小时]
你可以:
from datetime import date, timedelta
hours = [ 876600, 876624, 876648, 1017528, 1017552, 1017576]
base = date(1900, 1, 1)
for hour in hours:
base + timedelta(hours=hour)
2000-01-02
2000-01-03
2000-01-04
2016-01-30
2016-01-31
2016-02-01
如果您需要 hour
等信息,请使用 datetime
而不是 date
。
或使用 pd.DataFrame
:
df = pd.DataFrame(hours, columns=['hours'])
df['date'] = df.hours.apply(lambda x: base + timedelta(hours=x))
hours date
0 876600 2000-01-02
1 876624 2000-01-03
2 876648 2000-01-04
3 1017528 2016-01-30
4 1017552 2016-01-31
5 1017576 2016-02-01
使用 .apply
的解决方案效率极低,更不用说非惯用的和丑陋的了。 pandas 已经内置了进行时间增量转换的矢量化方法。
In [17]: hours = [ 876600, 876624, 876648, 1017528, 1017552, 1017576]*10000
In [18]: df = pd.DataFrame(hours, columns=['hours'])
In [19]: %timeit df.hours.apply(lambda x: base + timedelta(hours=x))
10 loops, best of 3: 74.2 ms per loop
In [21]: %timeit pd.to_timedelta(df.hours, unit='h') + Timestamp(base)
100 loops, best of 3: 11.3 ms per loop
In [23]: (pd.to_timedelta(df.hours, unit='h') + Timestamp(base)).head()
Out[23]:
0 2000-01-02
1 2000-01-03
2 2000-01-04
3 2016-01-30
4 2016-01-31
Name: hours, dtype: datetime64[ns]
执行此操作的理想方法是使用 netCDF4 num2date
import netCDF4
ncfile = netCDF4.Dataset('./foo.nc', 'r')
time = ncfile.variables['time']
dates = netCDF4.num2date(time[:], time.units, time.calendar)