【问题标题】:Finding out Age in Months and Years given DOB in a CSV using python使用 python 在 CSV 中找出给定 DOB 的月份和年份的年龄
【发布时间】:2013-05-12 21:53:24
【问题描述】:

我对自动生成的 CSV 报告进行了几项调整。我目前被困在需要获取患者的出生日期并将其转换为以月和年为单位的年龄的部分。原始 CSV 中已经有一个年龄列,我已经弄清楚如何转换 DOB 列中的数据以找到以天为单位的年龄,但是,我需要能够将其转换为月/年,然后还取该计算值并替换当前字段中的值。当前字段是手动输入的字符串,没有真正一致的格式。实际的 CSV 大约有 1700 行和 18 列,并使用标准逗号分隔它们,所以我只是制作一个较短的形式作为示例,并使用缩进使其更易于查看:

Last_Name   First_Name   MI   age                 DOB          SSN         visit_date
Stalone     Frank        P    62yrs 10 months     07-30-1950   123456789   05-02-2013
Astley      Richard      P    47years3mo          02-06-1966   987654321   05-03-2013

我想要的应该是这样的:

Last_Name   First_Name   MI   Age       DOB          SSN
Stalone     Frank        P    62y10mo   07-30-1950   123456789
Astley      Richard      P    47y3mo    02-06-1966   987654321

编辑:我意识到我可以直接使用 date.year 和 date.month 来减去年份和月份,从而更容易找到这些值。我现在正在编辑我的代码,并会在它工作时更新它,但是我仍然对我的问题的第二部分有问题。

到目前为止我的代码:

import re
import csv
import datetime

with open(inputfile.csv','r') as fin, open(outputfile.csv','w') as fout:
   reader = csv.DictReader(fin)
   fieldnames = reader.fieldnames
   writer_clinics = csv.DictWriter(fout, fieldnames, dialect="excel")
   writer_clinics.writeheader()

   for row in reader:
    data = next(reader)
    today = datetime.date.today()
    DOB = datetime.datetime.strptime(data["DOB"], "%m/%d/%Y").date()
age_y = (today.year - DOB.year)
age_m = (today.month - DOB.month)

if age_m < 0:
    age_y = age_y - 1
    age_m = age_m + 12

age = str(age_y) + " y " + str(age_m) + " mo "
print (age)

所以,我正在尝试弄清楚如何将年龄写入 outputfile.csv 中的正确字段?

更新 2:设法将大部分内容写入,但是,在输入文件中某些字段为空时出现错误。我的老板还希望我根据约会的实际日期确定年龄。我当前的代码块:

import re
import csv
import datetime

def getage(visit, dob):
    years = visit.year - dob.year
    months = visit.month - dob.month
    if visit.day < dob.day:
        months -= 1
    if months < 0:
        months += 12
        years -= 1
    return '%sy%smo'% (years, months)

with open('inputfile.csv','r') as fin, open('outputfile.csv','w') as fout:
    reader = csv.DictReader(fin)
    writer_clinics = csv.DictWriter(fout, reader.fieldnames, dialect="excel")
    writer_clinics.writeheader()

    for data in reader:
        visit_date = datetime.strptime(data["visit_date"], "%m-%d-%Y").date()
        DOB = datetime.datetime.strptime(data["DOB"], "%m-%d-%Y").date()
        data["Age"] = getage(visit_date, DOB)
        writer_clinics.writerow(data)

【问题讨论】:

  • 看起来很简单。从当前年份中减去 DOB 年份并添加 DOB 月份数。
  • 为什么需要转换DOB? “年龄”字段已经是几个月和几年。难道你不能只使用正则表达式来解析现有的“年龄”字段并让它看起来完全符合你的要求吗?
  • @HunterMcMillen 是的,我什至没有想到这一点。这更容易。
  • @kevlar1818 许多“年龄”字段也已过时。该报告是在将年龄手动输入系统后数周甚至数月生成的。当我在报表上运行这个脚本时,我的老板希望它不仅要确保格式统一,还要确保数据尽可能是最新的。
  • @Owenlars2 我正在研究解决方案,我会尽快发布。

标签: python datetime csv replace


【解决方案1】:

您无法将天转换为年和月,因为年和月的天数不同。您需要自己考虑年月的差异。

dob = datetime.datetime.strptime('07-30-1950', '%m-%d-%Y')
now = datetime.datetime.now()
years = now.year - dob.year
months = now.month - dob.month
if now.day < dob.day:
    months -= 1
while months < 0:
    months += 12
    years -= 1
age = '{}y{}mo'.format(years, months)

>>> print age
62y9mo

【讨论】:

  • 这也有效,而且我认为它比我最初做的要干净一些。谢谢。
【解决方案2】:

此代码使用Mark Ransom's algorithm 来获取正确的年龄。这会按照您在问题中的要求填充输出 CSV 文件。

import re
import csv
import datetime

def getage(now, dob):
    years = now.year - dob.year
    months = now.month - dob.month
    if now.day < dob.day:
        months -= 1
        while months < 0:
            months += 12
            years -= 1
    return '%sy%smo'% (years, months)

with open('inputfile.csv','r') as fin, open('outputfile.csv','w') as fout:
    reader = csv.DictReader(fin)
    writer_clinics = csv.DictWriter(fout, reader.fieldnames, dialect="excel")
    writer_clinics.writeheader()

    for data in reader:
        today = datetime.date.today()
        DOB = datetime.datetime.strptime(data["DOB"], "%m-%d-%Y").date()
        data["Age"] = getage(today, DOB)
        writer_clinics.writerow(data)

注意:我仅使用您在上面提供的 CSV 文件来测试此代码。

【讨论】:

  • 这主要是可行的,但我遇到了一些错误,我认为这主要与 csv 中的一些数据不稳定有关,当我开始运行时我会发布最终脚本(或者如果它在一小时左右后无法正常工作,请寻求更多帮助。谢谢!
  • 对于初学者,我建议使用 try/except 块来捕获格式错误的 CSV 错误等。
  • 好的,首先,我更改了脚本以适应我的特定程序的其余部分。这意味着更改输入文件,将日期中的连字符更改为斜线,并确保标题与 cvs 中显示的标题完全相同。其次,我将“while”更改为另一个“if”,并确保它不在前一个“if”的条件下。该脚本运行良好,直到它在 CSV 上出现空值的一行(例如,未命名的婴儿,没有中间首字母的人),然后它崩溃并给出 'TypeError: sequence item 0: expected string, NoneType found' .
  • 除此之外,它似乎正在编写文件。
  • @Owenlars2 我上面代码中的哪一行发生了这种情况?基本上你需要做的就是在使用任何东西之前检查if not data[whatever]:并以这种方式处理它。
【解决方案3】:

你试过eGenix DateTime包吗?:

>>> import mx.DateTime as dt
>>> a = dt.DateTime(2000, 1, 1)
>>> b = dt.DateTime(2013, 6, 17)
>>> x = dt.Age(b, a)
>>> x.years
13
>>> x.months
5  

【讨论】:

  • 我对此一无所知,尽管我的工作计算机不让我去那个下载站点。它非常挑剔:/ 我想出了一个内置的解决方案来解决我的那部分问题,不过还是谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-02-13
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多