pandas、python 中的数据解析

Data parsing in pandas, python

我有一个包含很多列的 excel 文件,其中一列 'Column3' 是带有一些文本的日期,基本上它看起来像这样:

26/05/20
XXX
YYY
12/05/2020

数据以DD/MM/YY格式写入,但pandas,就像excel一样,认为12/05/2020是2020年12月5日,而它是2020年5月12日。(我的 windows 设置为美国日期格式)

重要说明:当我打开股票 excel 文件时,带有 12/05/2020 的单元格已经是日期类型,尝试将其转换为文本时它会给我 44170 如果我只是将其重新格式化为 DD/MM/YY

我添加了这行代码:

iport pandas as pd
    
dateparse = lambda x: pd.datetime.strptime(x,'%d/%m/%y')
df = pd.read_excel("my_file.xlsx", parse_dates=['Column3'], date_parser=dateparse)

但是列中的文本会产生错误。

ValueError: time data 'XXX' does not match format '%d/%m/%y'

我更进一步,手动删除了所有文本(显然我不能一直这样做)以查看它是否有效,但随后出现以下错误

dateparse = lambda x: pd.datetime.strptime(x,'%d/%m/%y')
TypeError: strptime() argument 1 must be str, not datetime.datetime

我也试过这个:

df['Column3'] = pd.to_datetime(df.Column3, format ='%d/%m/%y', errors="coerce") 
# if I make errors="ignore" it doesn't change anything.

在这种情况下,我的 26/05/20 已正确转换为 2020 年 5 月 26 日,但我丢失了所有文本数据(没关系)和其他与我的格式参数不匹配的日期。因为之前他们被识别为美式日期。

我的 objective 是 将 Column3 中的数据转换为相同的格式,以便我可以使用 pandas 应用过滤器。 我认为这是几个解决方案:

  1. 告诉Pandas根本不要将文本转换为日期(但它已经在库存文件中保存为日期类型,可以吗?)
  2. 以某种方式忽略文本值并使用 date_parser= 方法将添加日期转换为 DD/MM/YY
  3. 在 pd.to_datetime 的帮助下将 26/05/20 转换为 2020 年 5 月 26 日,然后将 2020-09-06 00:00:00 转换为 2020 年 6 月 9 日(似乎是最简单的但忽略参数不起作用。)

这里是 link 小示例文件 https://easyupload.io/ca5p6w

我认为,首先您应该导入不带日期解析的文件,然后使用以下方法将其转换为日期格式:

df['column3']=pd.to_datetime(df['column3'],错误='coerce')

希望这会奏效

您可以将 date_parser 传递给 read_excel:

dateparser = lambda x: pd.to_datetime(x, dayfirst=True)

pd.read_excel('test.xlsx', date_parser = dateparser)

发布此作为答案,因为评论太长了

问题出在Excel。如果我在 Excel 中打开它,我会看到 2 个看起来像日期 26/05/2005/12/202006/02/2020 的字符串。请注意 202020 之间的区别 在第 24 行和第 48 行,我在 Column4 中看到了日期。这似乎表明 Excel 是放在一起的。这是 Excel 是通过复制粘贴还是以编程方式组装的?

仅使用 pd.read_excel 加载它会给出以下日期的结果:

  • 20 年 5 月 26 日
  • 2020-12-0500:00:00
  • 2020-02-0600:00:00

如果我这样做 df["Column3"].apply(type) 给我

  • 海峡

所以在 Excel 文件中这些被标记为日期时间。

使用 df = pd.read_excel(DATA_DIR / "sample.xlsx", dtype={"Column3": str}) 加载它们会将所有类型更改为 str,但不会更改输出。

如果您打开解压文件,然后直接查看 xml 文件 xl\worksheets\sheet1.xml 并查找单元格 C26,您会看到它是 44170,而 C5 是 6,这是对 xl/sharedStrings.xml

26/05/20 的引用

你如何'make'这个Excel文件?这可以最好地解决这个文件是如何放在一起的。


解决方法

作为解决方法,您可以逐步转换日期。不同的格式允许这样:

format1 = "%d/%m/%y"
format2 = "%Y-%d-%m %H:%M:%S"

然后你可以 pd.to_datetime(dates, format=format1, errors="coerce") 只获取第一个日期,NaT 获取不符合格式的日期。然后你用combine_first来填补空白。

dates = df["Column3"]  # of the one imported with dtype={"Column3": str}
dates_parsed = (
    pd.to_datetime(dates, format=format1, errors="coerce")
    .combine_first(pd.to_datetime(dates, format=format2, errors="coerce"))
    .astype(object)
    .combine_first(dates)
)

需要 astype(object) 用字符串值填充空白处。