我有以下格式的CSV文件:
name, lat, lon, alt, time
id1, 40.436047, -74.814883, 33000, 2016-01-21T08:08:00Z
我正在尝试使用Python将时间分成新列,所以它看起来像这样:
name, lat, lon, alt, year, month, day, hour, min, sec
id1, 40.436047, -74.814883, 33000, 2016,-01,-21, 08, 08, 00
我还想将浮点列中的位数设置为始终设置为5位小数。
这是我到目前为止的脚本:
import numpy as np
name,lat,lon,alt,time = np.loadtxt(
'test_track.csv',
delimiter=',',
dtype='str',
skiprows=1,
unpack = True
)
year = time[0:3]
print year
不幸的是,它没有将时间解析为年份,而是打印出第一个完整时间而不是仅仅是一年。
答案 0 :(得分:2)
[编辑+实际上这次在我的电脑上运行了..]
与其他提到的一样,我认为使用内置库来做你想做的事就足够了。使用dateutil解析器应该允许您以简单的方式使用datetime列。
但是如果您仍想重新创建CSV文件......
要以您希望的格式创建新的CSV文件,您可以执行以下操作:
#!/usr/bin/env python
import dateutil.parser
import csv
with open('original.csv', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
write_file = open("new.csv", 'w')
reading_label_line = True
for row in reader:
if reading_label_line:
reading_label_line = False
write_file.write("name, lat, lon, alt, year, month, day, hour, min, sec\n")
else:
dt = dateutil.parser.parse(row[-1])
row = row[0:len(row)-1] # cut off the last item (datetime)
row.append(dt.year)
row.append(dt.month)
row.append(dt.day)
row.append(dt.hour)
row.append(dt.minute)
row.append(dt.second)
write_file.write(', '.join(str(x) for x in row) + '\n')
如果你想保留' - '在月和日前,只需在dt.month和dt.day之前添加短划线。
答案 1 :(得分:0)
您应该尝试使用Pandas而不是numpy导入数据。 Panda read_csv很好地处理日期
尝试这样的事情
import pandas as pd
yourData = pd.read_csv(yourData_Path,delimiter = ',',skiprows = 0,
parse_dates={'time':[-1]},header = 1,na_values = -9999)
Pandas还允许您按日期时间进行索引,这非常好:)
答案 2 :(得分:0)
这个答案跟随您使用loadtxt
的主角,希望能够解释您所获得的内容以及替代方案。但是,如果您没有进行任何计算,那么只需读取每一行,拆分它并以所需格式将其写回来可能更简单。 csv
读者可以使该任务更简单,但不是必需的。纯Python行读写,字符串操作都可以。
============
使用样本的字符串副本(PY3中的字节字符串):
In [296]: txt=b"""name, lat, lon, alt, time
...: id1, 40.436047, -74.814883, 33000, 2016-01-21T08:08:00Z
...: id2, 40.436047, -74.814883, 33000, 2016-01-21T08:08:00Z""".splitlines(
...: )
In [297]: txt
Out[297]:
[b'name, lat, lon, alt, time',
b'id1, 40.436047, -74.814883, 33000, 2016-01-21T08:08:00Z',
b'id2, 40.436047, -74.814883, 33000, 2016-01-21T08:08:00Z']
In [298]: data=np.loadtxt(txt,delimiter=',',dtype=np.string_,skiprows=1)
In [299]: data
Out[299]:
array([[b'id1', b' 40.436047', b' -74.814883', b' 33000',
b' 2016-01-21T08:08:00Z'],
[b'id2', b' 40.436047', b' -74.814883', b' 33000',
b' 2016-01-21T08:08:00Z']],
dtype='|S21')
In [300]: data[:,4]
Out[300]:
array([b' 2016-01-21T08:08:00Z', b' 2016-01-21T08:08:00Z'],
dtype='|S21')
或者解压缩
In [302]: name,lat,lon,alt,time=np.loadtxt(txt,delimiter=',',dtype=np.string_,sk
...: iprows=1,unpack=True)
In [303]: time
Out[303]:
array([b' 2016-01-21T08:08:00Z', b' 2016-01-21T08:08:00Z'],
dtype='|S21')
我们已将文件加载为2d字符串数组或5个1d数组。 time
是一个字符串数组。
我可以将这个字符串数组转换为数据时对象数组:
In [307]: time1 = time.astype(np.datetime64)
In [308]: time1
Out[308]: array(['2016-01-21T08:08:00', '2016-01-21T08:08:00'], dtype='datetime64[s]')
In [309]: time1[0]
Out[309]: numpy.datetime64('2016-01-21T08:08:00')
我甚至可以用日期时间直接加载它。但这并不能解决您的显示问题。
=====================
genfromtxt
为加载不同的列类型提供了更多的力量
In [312]: np.genfromtxt(txt,dtype=None,skip_header=1,delimiter=',')
Out[312]:
array([(b'id1', 40.436047, -74.814883, 33000, b' 2016-01-21T08:08:00Z'),
(b'id2', 40.436047, -74.814883, 33000, b' 2016-01-21T08:08:00Z')],
dtype=[('f0', 'S3'), ('f1', '<f8'), ('f2', '<f8'), ('f3', '<i4'), ('f4', 'S21')])
这给出了字符串,浮点数和int的混合。日期仍然是字符串。
如果我用特定的dtype替换dtype=None
,我可以像以前一样约会:
In [313]: dt=['S3','f','f','i','datetime64[s]']
In [315]: data=np.genfromtxt(txt,dtype=dt,skip_header=1,delimiter=',')
In [316]: data
Out[316]:
array([ (b'id1', 40.4360466003418, -74.81488037109375, 33000, datetime.datetime(2016, 1, 21, 8, 8)),
(b'id2', 40.4360466003418, -74.81488037109375, 33000, datetime.datetime(2016, 1, 21, 8, 8))],
dtype=[('f0', 'S3'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<i4'), ('f4', '<M8[s]')])
In [317]: data['f4']
Out[317]: array(['2016-01-21T08:08:00', '2016-01-21T08:08:00'], dtype='datetime64[s]')
===============
第一次将此写回文件
In [318]: np.savetxt('test.txt',data,fmt='%4s, %.5f, %.5f, %d, %s')
In [320]: cat test.txt
b'id1', 40.43605, -74.81488, 33000, 2016-01-21T08:08:00
b'id2', 40.43605, -74.81488, 33000, 2016-01-21T08:08:00
控制浮动精度是显而易见的。我需要修复第一个字节的字符串显示。并且它没有分割日期 - 我只是显示正常的字符串表示。
=================
您可以将np.datetime64
数组转换为datetime
个对象数组:
In [361]: from datetime import datetime
In [362]: data['f4'].astype(datetime)
Out[362]:
array([datetime.datetime(2016, 1, 21, 8, 8),
datetime.datetime(2016, 1, 21, 8, 8)], dtype=object)
我可以使用逗号分隔符将其转换为字符串数组:
In [383]: tfmt='%Y, %m, %d, %H, %M, %S'
In [384]: timefld=data['f4'].astype(datetime)
In [385]: timefld = np.array([d.strftime(tfmt) for d in timefld])
In [386]: timefld
Out[386]:
array(['2016, 01, 21, 08, 08, 00', '2016, 01, 21, 08, 08, 00'],
dtype='<U24')
=========================
纯文本编辑方法可以使用
之类的功能def foo(dtstr):
return dtstr.replace(b'-',b', ').replace(b':',b', ').replace(b'T',b', ').replace(b'Z',b'')
def foo(dtstr):
# cleaner version with re
import re
return re.sub(b'[-:T]',b', ',dtstr[:-1])
def editline(aline):
aline=aline.split(b',')
aline[4]=foo(aline[4])
return b', '.join(aline)
In [408]: [editline(aline) for aline in txt[1:]]
Out[408]:
[b'id1, 40.436047, -74.814883, 33000, 2016, 01, 21, 08, 08, 00',
b'id2, 40.436047, -74.814883, 33000, 2016, 01, 21, 08, 08, 00']