2017-07-08 69 views
0

我有一個名爲start_date的字段的CSV文件,其中包含各種格式的數據。我如何正常化csv文件中的日期? python

某些格式包括例如June 23, 19125/11/1930(月,日,年)。但並非所有的值都是有效日期。

我想在start_date列旁邊添加一個start_date_description字段,以將無效日期值過濾爲。最後,將start_date中的所有有效日期值歸一化爲ISO 8601(即,YYYY-MM-DD)。

到目前爲止,我只能將start_date加載到我的文件中,我卡住了,並且會很感激螞蟻的幫助。請任何解決方案,特別是不使用庫將是偉大的!

import csv 

date_column = ("start_date") 
f = open("test.csv","r") 
csv_reader = csv.reader(f) 

headers = None 
results = [] 
for row in csv_reader: 
    if not headers: 
     headers = [] 
     for i, col in enumerate(row): 
      if col in date_column: 
      headers.append(i) 
    else: 
     results.append(([row[i] for i in headers])) 

print results 

enter image description here

+0

也許['dateparser'模塊](https://dateparser.readthedocs。io/en/latest /)可以在這裏幫助你,如果你不知道你正在接收的日期的確切格式 –

回答

3

的一種方法是使用dateutil模塊,你可以按照如下分析數據:

from dateutil import parser 
parser.parse('3/16/78') 
parser.parse('4-Apr') # this will give current year i.e. 2017 

然後解析到您的格式可以通過

dt = parser.parse('3/16/78') 
dt.strftime('%Y-%m-%d') 

完成假設你有一個數據幀格式的表,你現在可以定義解析函數a ND適用於列如下:

def parse_date(start_time): 
    try: 
     return parser.parse(x).strftime('%Y-%m-%d') 
    except: 
     return '' 
df['parse_date'] = df.start_date.map(lambda x: parse_date(x)) 
+0

如何運行你的例子由整個csv文件評估? – Vash

+0

我更新了我的解決方案。請讓我知道這對你有沒有用。我假設你的數據框具有'start_date'作爲列 – titipata

1

問題 ...添加start_date_description ... ...正常化ISO 8601的

這讀取文件test.csv和驗證日期字符串列start_date與日期指令模式並返回 dict{description, ISO}。返回的dict用於更新當前的行dict,更新的行dict寫入文件test_update.csv

把它放在一個新的Python文件中並運行它!

缺少有效的日期指令模式可以簡單地添加到數組中。

的Python»3.6文檔:8.1.8. strftime() and strptime() Behavior

from datetime import datetime as dt 
import re 

def validate(date): 
    def _dict(desc, date): 
     return {'start_date_description':desc, 'ISO':date} 

    for format in [('%m/%d/%y','Valid'), ('%b-%y','Short, missing Day'), ('%d-%b-%y','Valid'), 
        ('%d-%b','Short, missing Year')]: #, ('%B %d. %Y','Valid')]: 
     try: 
      _dt = dt.strptime(date, format[0]) 
      return _dict(format[1], _dt.strftime('%Y-%m-%d')) 
     except: 
      continue 

    if not re.search(r'\d+', date): 
     return _dict('No Digit', None) 

    return _dict('Unknown Pattern', None) 

with open('test.csv') as fh_in, open('test_update.csv', 'w') as fh_out: 
    csv_reader = csv.DictReader(fh_in) 
    csv_writer = csv.DictWriter(fh_out, 
           fieldnames=csv_reader.fieldnames + 
              ['start_date_description', 'ISO']) 
    csv_writer.writeheader() 

    for row, values in enumerate(csv_reader,2): 
     values.update(validate(values['start_date'])) 

     # Show only Invalid Dates 
     if any(w in values['start_date_description'] 
       for w in ['Unknown', 'No Digit', 'missing']): 

      print('{:>3}: {v[start_date]:13.13} {v[start_date_description]:<22} {v[ISO]}'. 
        format(row, v=values)) 

     csv_writer.writerow(values) 

輸出

start_date start_date_description ISO 
June 23. 1912 Valid     1912-06-23 
12/31/91  Valid     1991-12-31 
Oct-84  Short, missing Day  1984-10-01 
Feb-09  Short, missing Day  2009-02-01 
10-Dec-80  Valid     1980-12-10 
10/7/81  Valid     1981-10-07 
Facere volupt No Digit    None 
... (omitted for brevity) 

與Python測試:3.4.2

+0

我運行了你的代碼,它不起作用,它繼續說「_data」沒有被定義。我把你的代碼直接放在地雷下面,然後運行它。有什麼建議麼? – Vash

+0

文件名稱在我上傳的圖像上,是否應該將_data更改爲文件名? – Vash

+0

我再次運行它,只有你在sDate中的內容被打印到控制檯,實際的文件沒有被評估。 – Vash

相關問題