使用正则表达式过滤熊猫
Posted
技术标签:
【中文标题】使用正则表达式过滤熊猫【英文标题】:Filtering in pandas using regex expression 【发布时间】:2017-06-18 19:46:07 【问题描述】:我正在使用 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 月和 10 月之间)。所以基本上在过滤器之后我会有这样的东西
ID Actual Date
738564 01/21/2016
274628 02/12/2016
571749 03/30/2016
718563 10/01/2016
103216 07/16/2014
446754 08/06/2015
133346 01/16/2011
234682 N/A
238756 (none)
我使用的代码是:
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 年的日期。 非常感谢您的帮助,对于英语不好表示抱歉
【问题讨论】:
【参考方案1】: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
dtype:
In [181]: df['ActualDate'] = pd.to_datetime(df['ActualDate'], errors='coerce')
In [182]: df
Out[182]:
ID ActualDate
0 738564 2016-01-21
1 274628 2016-02-12
2 571749 2016-03-30
3 718563 2016-10-01
4 984739 2016-11-30
5 938511 2016-12-24
6 103216 2014-07-16
7 446754 2015-08-06
8 135654 2017-02-01
9 135614 2017-01-16
10 133346 2011-01-16
11 234682 NaT
12 238756 NaT
使用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
更新:如果您想在字符串 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)
【讨论】:
好的,我认为最好的办法是将日期转换为日期时间,但是某些命运值是 None 或 NA,我也需要显示这些值。任何选择,因为我认为 datetime 不接受字符串。代码是这样的 @CarlosArronteBello,您是否希望在结果数据集中(过滤后)包含Date
为None
或NaN
的行?
是的,我需要 None 和 NA 以及 2016 年 10 月之前的所有日期(包括 octuber)。非常感谢你
ok 看起来对我有用,让我试试代码,只是一个简单的问题,返回将是 NaT 或将是 None 和 Na 的字符串,日期格式也可以成为mm/dd/yyyy,抱歉打扰,我基本上是新来的。并感谢您的帮助
如果您希望能够在ActualDate
列上使用矢量化(快速读取)操作,那么您希望将其设为datetime64
dtype。这也意味着您将拥有NaT
(不是时间)而不是所有无法转换为日期的值,并且您将拥有默认表示形式(它在屏幕上显示的方式):yyyy-mm-dd .您可以使用任何您想要的格式将其转换为字符串,但是您将失去灵活性并且您将不得不使用字符串...以上是关于使用正则表达式过滤熊猫的主要内容,如果未能解决你的问题,请参考以下文章