将pandas数据帧中的无效日期转换为最接近的有效日期



我有以下名为df、的数据帧

Date        Data
05/30/2023  3.733
05/30/2022  3.294
05/30/2021  2.391
02/30/2021  1.807
11/30/2020  1.766
08/31/2020  1.920
05/31/2020  1.830
02/29/2020  2.960
11/30/2019  2.860
08/31/2019  2.680
05/31/2019  2.490
02/28/2019  2.560
11/30/2018  2.560
08/31/2018  2.500
05/31/2018  2.400
02/28/2018  2.310
11/30/2017  2.310
08/31/2017  2.350
05/31/2017  2.510
02/28/2017  2.400
11/30/2016  2.270
08/31/2016  2.220
05/31/2016  2.160
02/29/2016  2.160
11/30/2015  2.055

我可以看到第4个条目的日期无效。(一月份只有28或29天(我以前试图使用pd.to_datetime函数转换日期索引,但一直出现错误。所以我试了一下。

df['tempdate'] = pd.to_datetime(df.index, errors='coerce')

这张表就是


Date        Data    tempdate
05/30/2023  3.733   2023-05-30
05/30/2022  3.294   2022-05-30
05/30/2021  2.391   2021-05-30
02/30/2021  1.807   NaT
11/30/2020  1.766   2020-11-30
08/31/2020  1.920   2020-08-31
05/31/2020  1.830   2020-05-31
02/29/2020  2.960   2020-02-29
11/30/2019  2.860   2019-11-30
08/31/2019  2.680   2019-08-31
05/31/2019  2.490   2019-05-31
02/28/2019  2.560   2019-02-28
11/30/2018  2.560   2018-11-30
08/31/2018  2.500   2018-08-31
05/31/2018  2.400   2018-05-31
02/28/2018  2.310   2018-02-28
11/30/2017  2.310   2017-11-30
08/31/2017  2.350   2017-08-31
05/31/2017  2.510   2017-05-31
02/28/2017  2.400   2017-02-28
11/30/2016  2.270   2016-11-30
08/31/2016  2.220   2016-08-31
05/31/2016  2.160   2016-05-31
02/29/2016  2.160   2016-02-29
11/30/2015  2.055   2015-11-30

问题是,我有很多这样的数据帧,错误可能是随机的几个月,本应是30天,但它们显示为31天。

我只想从任何一个出现NaT错误的日期中减去3天。但由于这些日期不被视为日期,我似乎无法从中减去3天。

有没有一个pandas命令可以用程序修复这个错误?

我试过

df.index = np.where(df['tempdate'].isna(), pd.to_datetime(df.index), pd.to_datetime(df['tempdate']-np.timedelta64(3,'D')))

但我仍然有一个错误,那就是当天超出了范围。

我还尝试将日期分解为不同的strings,并将其转换为int,以使用减去3天

df.index = np.where(df['tempdate'].isna(), df.index, pd.to_datetime(int(df.index.astype(str).str.split('/')[0]),int(df.index.astype(str).str.split('/')[1])-3,int(df.index.astype(str).str.split('/')[2])))

但是我得到了这个错误,

TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

处理此类错误的最佳方法是什么?如何将此无效日期转换为最近的有效日期?

您可以转换您可以转换的内容,然后使用正则表达式替换中断的天数,然后更新您以前尝试的转换。

def subtract_3_days(match):
days = int(match.group(1))
return str(days - 3)
tempdate = pd.to_datetime(df["Date"], format="%m/%d/%Y", errors="coerce")
fixed_dates = df.loc[tempdate.isna(), "Date"].str.replace(r"(?<=/)(d+)(?=/)", subtract_3_days)
tempdate.update(pd.to_datetime(fixed_dates, format="%m/%d/%Y"))
df["proper_dates"] = tempdate
print(df)
Date   Data proper_dates
0   05/30/2023  3.733   2023-05-30
1   05/30/2022  3.294   2022-05-30
2   05/30/2021  2.391   2021-05-30
3   02/30/2021  1.807   2021-02-27
4   11/30/2020  1.766   2020-11-30
5   08/31/2020  1.920   2020-08-31
6   05/31/2020  1.830   2020-05-31
7   02/29/2020  2.960   2020-02-29
8   11/30/2019  2.860   2019-11-30
9   08/31/2019  2.680   2019-08-31
10  05/31/2019  2.490   2019-05-31
11  02/28/2019  2.560   2019-02-28
12  11/30/2018  2.560   2018-11-30
13  08/31/2018  2.500   2018-08-31
14  05/31/2018  2.400   2018-05-31
15  02/28/2018  2.310   2018-02-28
16  11/30/2017  2.310   2017-11-30
17  08/31/2017  2.350   2017-08-31
18  05/31/2017  2.510   2017-05-31
19  02/28/2017  2.400   2017-02-28
20  11/30/2016  2.270   2016-11-30
21  08/31/2016  2.220   2016-08-31
22  05/31/2016  2.160   2016-05-31
23  02/29/2016  2.160   2016-02-29
24  11/30/2015  2.055   2015-11-30

分解:

  • tempdate = pd.to_datetime(df["Date"], format="%m/%d/%Y", errors="coerce")将我们所能转换为日期时间。如果它导致不正确的日期时间,那么我们将以NaT值结束。将这个数组存储到一个名为"的变量中;tempdate";

  • fixed_dates = df.loc[tempdate.isna(), "Date"].str.replace(r"(?<=/)(d+)(?=/)", subtract_3_days)

    • df.loc[tempdate.isna(), "Date"]->无论tempdate在哪里具有NaT值,都可以在我们的原始"中找到相应的字符串;日期";我们df的专栏
    • 从转换不好的字符串子集中的.str.replace(r"(?<=/)(d+)(?=/)", subtract_3_days),找到该数组中被正斜杠包围的所有数字。(例如,在这个模式上匹配:"/数字/"以获得数字(。然后,当我们找到匹配项时,通过subtract_3_days函数运行它,将该匹配项转换为整数,减去3,并将新值作为字符串返回。这将保留斜杠(月份和年份(之前或之后的任何数字。现在我们有一个字符串数组;"天";值基本上已经从中减去了3天
  • tempdate.update(pd.to_datetime(fixed_dates, format="%m/%d/%Y"))既然我们确定了日期,但它们仍然是字符串。我们需要转换它们,然后替换tempdate中的NaT值。

  • df["proper_dates"] = tempdate最后将我们的数组/系列添加回原始数据帧中,作为一个新列。

最新更新