2016-10-03 90 views
1

我有以下格式的CSV文件:拆分时间戳列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 

不幸的是,而不是分析的时间为一年,它打印出的第一个完整的时间刚好一年来代替。

+1

使用'datetime.strptime'解析出日期时间,不要分割它 –

+0

您是否试图将这些数据加载到一个或多个'numpy'数组中进行计算,或者您只是想重新格式化文件 - 也就是说,只需使用新格式将相同的数据写回文件?你不需要numpy来编辑文件。 – hpaulj

回答

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前添加短划线即可。

+0

什么是'read_file'? 'reader'?什么是'dt.year'行?这看起来不像'python'。 – hpaulj

+0

@hpaulj - 是的,你是对的......我的语法混合了不同的文件,并且在一些额外的行中我没有清理。感谢您指出! –

+0

@JiMun我试着运行你建议的代码,并得到了错误:python test.py 文件“test.py”,第7行 SyntaxError:第7行文件test.py中的非ASCII字符'\ xe2',但没有声明编码;详情请参阅http://python.org/dev/peps/pep-0263/ – Waterguy

0

你应该尝试导入数据与熊猫而不是numpy。熊猫read_csv处理日期相当不错

尝试这样的事情

import pandas as pd 
yourData = pd.read_csv(yourData_Path,delimiter = ',',skiprows = 0, 
      parse_dates={'time':[-1]},header = 1,na_values = -9999) 

大熊猫还允许您指数是相当不错的日期时间:)

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是一串字符串。

我这个字符串数组转换成DATATIME对象的数组:

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。日期仍然是字符串。

如果我有一个具体的D型更换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']