在Numpy中导出ISO日期
我刚开始学习Python,有个基本的问题在网上找不到解决办法。
我有一个名为IBTsample.txt的表格,内容如下:
- 季节, ISO时间, 纬度, 经度, 枚举
- 2009, 2009-12-24 12:00:00, 6.50, 85.00, 2
- 2009, 2009-12-25 06:00:00, 8.00, 84.50, 6
- 2009, 2009-12-25 00:00:00, 7.00, 84.50, 4
- 2009, 2009-12-24 18:00:00, 6.50, 85.00, 3
- 2009, 2009-12-24 09:00:00, 6.50, 85.00, 1
- 2009, 2009-12-25 03:00:00, 7.00, 84.50, 5
我想做的是把它导入为一个numpy数组,进行一些处理(目前只是按日期对记录进行排序),然后把处理后的表格导出到一个新的.txt文件中。
from numpy import *
import pylab
rawtable = loadtxt('IBTsample.txt', delimiter=',', skiprows=1, converters= {1:pylab.datestr2num},\
dtype={'names':('Season','ISO_time','Latitude','Longitude','Enum'),\
'formats':('uint16','float','float16','float16','uint8')})
sortable = (sort(rawtable, order=('ISO_time'))).copy()
savetxt('IBTsorted.txt', sortable, fmt='%d,%.3f,%.1f,%.1f,%d')
在导入时我需要使用pylab.datestr2num函数,但找不到一个反向函数来把日期和时间导出为ISO格式。
任何帮助或想法都会很有用。
2 个回答
1
除了@unutbu的回答,如果你使用的是最新版本的numpy(>= 1.7
),它有一个原生的日期数据类型。
在这种情况下,可以试试下面的代码:
import numpy as np
import dateutil.parser
rawtable = np.genfromtxt('test_in.txt', names=True, delimiter=',',
converters={1:dateutil.parser.parse},
dtype=[np.uint16, np.datetime64, np.float, np.float, np.uint8])
sorttable = np.sort(rawtable, order=('ISO_time'))
with open('test_out.txt', 'w') as outfile:
outfile.write(','.join(sorttable.dtype.names) + '\n')
np.savetxt(outfile, sorttable, fmt='%i,%r,%f,%f,%i')
这样会得到:
Season,ISO_time,Latitude,Longitude,Enum
2009,2009-12-24 09:00:00,6.500000,85.000000,1
2009,2009-12-24 12:00:00,6.500000,85.000000,2
2009,2009-12-24 18:00:00,6.500000,85.000000,3
2009,2009-12-25 00:00:00,7.000000,84.500000,4
2009,2009-12-25 03:00:00,7.000000,84.500000,5
2009,2009-12-25 06:00:00,8.000000,84.500000,6
3
你可以使用 matplotlib.dates.num2date
这个功能,把数字转换回日期时间对象。然后再调用 isoformat()
,这样就能把日期以 ISO-8601 格式的字符串形式输出。
import numpy as np
import matplotlib.dates as md
def num2isodate(num):
result=md.num2date(num).isoformat()
return result
rawtable = np.loadtxt(
'IBTsample.txt', delimiter=',', skiprows=1,
converters= {1:md.datestr2num},
dtype={'names':['Season','ISO_time','Latitude','Longitude','Enum'],
'formats':['uint16','float','f4','f4','uint8']})
把 ISO_time
的数据类型转换成 object
。这样这个列就可以先存放浮点数,后面再存放字符串。需要注意的是,下面的 astype
会返回一个副本,所以不需要再显式调用 copy
了。而且,因为你已经调用了 copy
,我假设在内存中保留两个数组副本不是问题。(如果内存紧张,我们可以用 csv 模块逐行写入数组,而不是用 np.savetxt
。但因为内存不是问题,使用 np.savetxt
更方便。)
sortable = rawtable.astype({'names':['Season','ISO_time','Latitude','Longitude','Enum'],
'formats':['uint16','object','f4','f4','uint8']})
sortable = np.sort(sortable, order=('ISO_time'))
sortable['ISO_time'] = [num2isodate(num) for num in sortable['ISO_time']]
np.savetxt('IBTsorted.txt', sortable, fmt='%d,%s,%.1f,%.1f,%d')
顺便说一句,我建议不要使用 from module import *
,特别是当 module
是 numpy
的时候。这会覆盖一些 Python 内置的功能,比如 abs
、all
、any
、min
、max
、sum
、round
等等。这样不仅让调用 Python 内置功能变得困难,还容易写出看起来没问题但实际上有难以发现或微妙错误的代码。