python - 使用 csv.DictReader 时的 datetime.strptime 问题

标签 python csv datetime

我有一个 CSV 文件,其中显示了一些基本的获救狗,包括它们何时进入救援以及何时被收养。我试图最终在 map 上进行可视化,以显示狗从一个区域移动到其他区域的位置。我正在研究的一个因素是一只特定的狗在被收养之前被寄养的时间有多长。

这是 CSV 文件的开头。

Name,Status,Sex,Animal_ID,Birthdate,Adopter_City,Adopter_State,Adopter_Zip,Foster_City,Foster_State,Foster_Zip,Created_Date,Adopted_Date,Length
Marnie,Adopted,Female,15598143,2019-03-24,Port Orchard,Wa,98367,Auburn,WA,98002,2020-04-22,2020-07-08
Kendra,Adopted,Female,15598254,2019-12-31,Austin,Tx,78731,Austin ,Tx,78723,2020-04-22,2020-05-01
Hope,Adopted,Female,15598264,2019-10-25,Springfield ,OR,97477,Austin,TX,78737,2020-04-22,2020-05-02
...

我使用 datetime.strptime 来格式化接收(进入寄养)和接收(收养)。然后我计算了停留时间= outtake - intake。代码正确计算了长度。

import csv
from datetime import datetime


with open('animals_20200826_12p46.csv', newline = '') as csvfile:
    data = csv.DictReader(csvfile)
   
    for row in data:
        if len(row['Adopted_Date']) < 1 :
            continue
        intake = datetime.strptime(row['Created_Date'], '%Y-%m-%d')
        outtake = datetime.strptime(row['Adopted_Date'], '%Y-%m-%d')
        length = outtake - intake
        row['Length'] = length
        
        print('In:', intake, 'Out:', outtake, 'In foster:', length)

返回结果如下:

In: 2020-04-22 00:00:00 Out: 2020-07-08 00:00:00 In foster: 77 days, 0:00:00
In: 2020-04-22 00:00:00 Out: 2020-05-01 00:00:00 In foster: 9 days, 0:00:00
In: 2020-04-22 00:00:00 Out: 2020-05-02 00:00:00 In foster: 10 days, 0:00:00
In: 2020-04-22 00:00:00 Out: 2020-06-01 00:00:00 In foster: 40 days, 0:00:00
...

然后我按照 How to update rows in a CSV file 中建议的步骤进行操作更新我的 CSV 文件。

import csv
from datetime import datetime
from tempfile import NamedTemporaryFile
import shutil

filename = 'animals_20200826_12p46.csv'
tempfile = NamedTemporaryFile(mode='w', delete=False)

fields = ['Name','Status','Sex','Animal_ID','Birthdate','Adopter_City','Adopter_State','Adopter_Zip','Foster_City','Foster_State','Foster_Zip','Created_Date','Adopted_Date','Length']

with open(filename, 'r') as csvfile, tempfile:
    reader = csv.DictReader(csvfile, fieldnames= fields)
    writer = csv.DictWriter(tempfile, fieldnames=fields)
    for row in reader:
        if len(row['Adopted_Date']) < 1 :  
            continue
        intake = datetime.strptime(row['Created_Date'], '%Y-%m-%d')
        outtake = datetime.strptime(row['Adopted_Date'], '%Y-%m-%d')
        row['Length'] = outtake - intake
        writer.writerow(row)

shutil.move(tempfile.name, filename)

for 循环的主要部分是相同的,但现在我遇到了如下回溯错误。

Traceback (most recent call last):
  File "CSV.py", line 18, in <module>
    intake = datetime.strptime(row['Created_Date'], '%Y-%m-%d')
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data 'Created_Date' does not match format '%Y-%m-%d'

我哪里错了?有什么方法比我目前的方法更好?

最佳答案

不同之处在于,在您使用的工作示例中

DictReader(csvfile)

而在您使用的非工作示例中

DictReader(csvfile, fieldnames=fields)

documentation说:

If fieldnames is omitted, the values in the first row of file f will be used as the fieldnames.

换句话说,如果省略 fieldnames,则使用第一行来确定字段名,否则它不会被使用,而是像迭代中的所有其他行一样发出。

这会导致包含列标题的初始行被传递到 strptime

我建议您再次为读者省略 fieldnames 参数。

关于python - 使用 csv.DictReader 时的 datetime.strptime 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63676176/

相关文章:

python - 使用 CBC 模式的 PyCrypto AES 256 加密 - 有什么弱点吗?

python - 在python中没有负值的情况下进行插值

mysql 将数据加载到本地主机文件中

javascript - 对重叠事件进行 Sequelize 查询

scala - 从字符串形式的日期中减去天数

php - 此功能是否有任何日期/时间可能会中断?

python - 在另一个方法中运行一个方法。 Python

带有 RaspberryPi 的 Python Ctypes

java - 通过java将带有unicode的表从mysql导出到csv文件

Python 在写入 CSV 文件之前检查列数据是否存在