用正则表达式筛选Pandas

2024-09-30 20:30:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用pandas和python在excel中做一些工作。我有这样的东西。在

  ID         Actual Date
738564     01/21/2016
274628     02/12/2016
571749     03/30/2016
718563     10/01/2016
984739     11/30/2016
938511     12/24/2016
103216     07/16/2014
446754     08/06/2015
135654     02/01/2017
135614     01/16/2017
133346     01/16/2011
234682        N/A
238756       (none)

所以我需要按日期过滤,但我只需要过滤2016年11月之前的年份日期(所以我需要过滤2014年、2015年以及2016年1月到octuber之间)。所以基本上在过滤器之后,我会有这样的东西

^{pr2}$

我使用的代码是:

    regex = r"[0-9]{2}/[0-9]{2}/2016"
df = pd.read_csv("Request.csv", keep_default_na=False)
df1 = df.loc[(df["Actual Date"].str.contains(r'[0-9]{2}/[0-9]{2}/2016') &
             (df["Actual Date"].str.contains("2015")) & 
             (df["Actual Date"].str.contains("2014")) &
             (df["Actual Date"].str.contains("2011")) &
             (df["Actual Date"].str.contains("(None)")) &
             (df["Actual Date"].str.contains("N/A"))))]                 

但当我运行代码时,我只收到了2011年、2014年和2015年。正则表达式在2016年不起作用。 很抱歉,我会很感激你的英语


Tags: csv代码noneid过滤器pandasdfdate
1条回答
网友
1楼 · 发布于 2024-09-30 20:30:50

RegEx是一个非常强大的工具,但在这种情况下,有一种更好的方法:

In [180]: df
Out[180]:
        ID  ActualDate
0   738564  01/21/2016
1   274628  02/12/2016
2   571749  03/30/2016
3   718563  10/01/2016
4   984739  11/30/2016
5   938511  12/24/2016
6   103216  07/16/2014
7   446754  08/06/2015
8   135654  02/01/2017
9   135614  01/16/2017
10  133346  01/16/2011
11  234682         NaN
12  238756      (none)

让我们转换它datetime数据类型:

^{pr2}$

使用boolean indexing筛选:

In [184]: df[(df['ActualDate'] < '2016-11-01') | df['ActualDate'].isnull()]
Out[184]:
        ID ActualDate
0   738564 2016-01-21
1   274628 2016-02-12
2   571749 2016-03-30
3   718563 2016-10-01
6   103216 2014-07-16
7   446754 2015-08-06
10  133346 2011-01-16
11  234682        NaT
12  238756        NaT

使用.query()方法筛选:

In [186]: df.query("ActualDate < '2016-11-01' or ActualDate != ActualDate")
Out[186]:
        ID ActualDate
0   738564 2016-01-21
1   274628 2016-02-12
2   571749 2016-03-30
3   718563 2016-10-01
6   103216 2014-07-16
7   446754 2015-08-06
10  133346 2011-01-16
11  234682        NaT
12  238756        NaT

更新:如果要在string dtype中保留原始Date

In [190]: df
Out[190]:
        ID Actual Date
0   738564  01/21/2016
1   274628  02/12/2016
2   571749  03/30/2016
3   718563  10/01/2016
4   984739  11/30/2016
5   938511  12/24/2016
6   103216  07/16/2014
7   446754  08/06/2015
8   135654  02/01/2017
9   135614  01/16/2017
10  133346  01/16/2011
11  234682         NaN
12  238756      (none)

首先添加一个新的datetime列:

In [191]: df['Date'] = pd.to_datetime(df['Actual Date'], errors='coerce')

In [192]: df
Out[192]:
        ID Actual Date       Date
0   738564  01/21/2016 2016-01-21
1   274628  02/12/2016 2016-02-12
2   571749  03/30/2016 2016-03-30
3   718563  10/01/2016 2016-10-01
4   984739  11/30/2016 2016-11-30
5   938511  12/24/2016 2016-12-24
6   103216  07/16/2014 2014-07-16
7   446754  08/06/2015 2015-08-06
8   135654  02/01/2017 2017-02-01
9   135614  01/16/2017 2017-01-16
10  133346  01/16/2011 2011-01-16
11  234682         NaN        NaT
12  238756      (none)        NaT

过滤:

In [194]: df.drop('Date', 1).loc[(df['Date'] < '2016-11-01') | df['Date'].isnull()]
Out[194]:
        ID Actual Date
0   738564  01/21/2016
1   274628  02/12/2016
2   571749  03/30/2016
3   718563  10/01/2016
6   103216  07/16/2014
7   446754  08/06/2015
10  133346  01/16/2011
11  234682         NaN
12  238756      (none)


In [196]: df.query("Date < '2016-11-01' or Date != Date").drop('Date', 1)
Out[196]:
        ID Actual Date
0   738564  01/21/2016
1   274628  02/12/2016
2   571749  03/30/2016
3   718563  10/01/2016
6   103216  07/16/2014
7   446754  08/06/2015
10  133346  01/16/2011
11  234682         NaN
12  238756      (none)

相关问题 更多 >