我如何规范化csv文件中的日期?蟒蛇

时间:2017-07-08 04:26:55

标签: python sorting datetime

我有一个CSV文件,其中包含一个名为$products = Product::where('category_id', $category->id)->where('status','published')->with('project')->sortBy(function($product) { return $product->project->like->count(); })->paginate(21); 的字段,其中包含各种格式的数据。

某些格式包括例如start_dateJune 23, 1912(月,日,年)。但并非所有值都是有效日期。

我想在5/11/1930列旁边添加start_date_description字段,以将无效的日期值过滤到。最后,将start_date中的所有有效日期值标准化为ISO 8601(即start_date)。

到目前为止,我只能将start_date加载到我的文件中,我被卡住并会感谢蚂蚁的帮助。请,任何解决方案,尤其是不使用图书馆都会很棒!

YYYY-MM-DD

enter image description here

2 个答案:

答案 0 :(得分: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')

假设您有数据帧格式的表,您现在可以定义解析函数并应用于列,如下所示:

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))

答案 1 :(得分:1)

  

问题:...添加一个start_date_description ... normalize ...到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