2016-10-03 118 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']