识别所有日期组合?

Identify all date combinations?

提问人:gravityflyer 提问时间:11/4/2023 更新时间:11/4/2023 访问量:66

问:

我最近接手了一个正在进行的研究项目,令我沮丧的是,我们的本科生研究助理似乎没有遵循我们关于日期条目的编码指南。最小工作示例如下,

import pandas as pd
MWE = [["05/2003"], ["10/1998"], ["1/4/2014"], ["12/09/1979"]]
df = pd.DataFrame(MWE)
df = df.rename(columns={0: 'year'})

有一些奇怪的球条目,即。“2005 年 9 月 12 日”和“20221204”,但据我所知,大多数条目似乎都遵循 、 或格式。%m%y%d%m%y%m%d%y

  1. 有超过 10k 行的数据,有没有办法快速识别所有不同的日期格式?我最初的方法是手动梳理数据以发现所有变化。这似乎有点乏味,想象有更好的方法吗?(我也是从 Stata 开始学习 Python的,这有点学习曲线。print(df["year"].value_counts())
  2. 理想情况下,我们希望同时保留月份年份,所以我不确定最佳解决方案。至少,如果我们想提取至少年份,我想我可以在适用的情况下使用,尽管在最后四位数字不构成年份的情况下,这显然会导致问题。df['year_only'] = df['year'].str[-4:]

关于如何解决这一困境的任何想法或建议将不胜感激!

Python 熊猫 日期时间

评论

3赞 teapot418 11/4/2023
你期望如何区分和区分?“12/09/1979”可以按任一顺序排列。“尝试解析它并遍历异常值”似乎是一种不错的方法。但数据可能总是至少部分糟糕。%d%m%y%m%d%y
1赞 ti7 11/4/2023
如果这些只是存储为字符串而不是日期时间数据(尚未),则需要另一个启发式方法来区分一些日期“ISO 8601 于 06 年 05 月 88 日发布,最近修订于 12 年 01 月 04 日。 xkcd.com/1179
0赞 Leonardo Gazdek 11/4/2023
除非您有一些额外的数据可以使用,否则无法真正知道 2014 年 1 月 4 日是指 4 月 1 日还是 1 月 4 日。是否有任何额外的数据可以用来得出结论?也许您可以使用助手的位置来确定他们可能习惯的日期格式?这可能并不完美,但在大多数情况下都会起作用。
0赞 gravityflyer 11/4/2023
啊,好点子——我什至没有想到这一点!

答:

1赞 Alexandr Ch 11/4/2023 #1

一种可能的方法可能是从数据帧中获取 pandas 系列,并使用 contains 方法应用合适的正则表达式来标识条目中遇到的日期:

https://pandas.pydata.org/docs/reference/api/pandas.Series.str.contains.html

评论

0赞 Community 11/5/2023
正如目前所写的那样,你的答案尚不清楚。请编辑以添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以在帮助中心找到有关如何写出好答案的更多信息。
0赞 mozway 11/4/2023 #2

我在这里展示了一种从字符串中识别可能的日期时间格式的方法。但是,就您而言,像 or 这样的日期存在很强的歧义,这些日期既有效又有效。1/4/201412/09/1979D/M/YM/D/Y

我建议使用不同的格式进行解析(仅使用/是一个很好的起点,然后您可以添加其他格式)。在第二次中,检查两天的位置是否可以产生不同的有效日期,您可能需要手动分析这些日期(如果您知道哪个学生填写了哪个日期,您也许可以确定使用的格式)。dayfirst=Truedayfirst=False

s1 = pd.to_datetime(df['year'], dayfirst=True)
s2 = pd.to_datetime(df['year'], dayfirst=False)
#s3 = pd.to_datetime(df['year'], format='%m/%Y')

df['ambiguous'] = s1!=s2
df['date'] = s1.fillna(s2)#.fillna(s3)

输出:

         year  ambiguous       date
0     05/2003      False 2003-05-01
1     10/1998      False 1998-10-01
2    1/4/2014       True 2014-04-01
3  12/09/1979       True 1979-09-12