在 Pandas 数据框中运行正则表达式循环

Posted

技术标签:

【中文标题】在 Pandas 数据框中运行正则表达式循环【英文标题】:Running a Regex loop in a Pandas Dataframe 【发布时间】:2017-01-16 19:08:03 【问题描述】:

我目前有一个日期列存在一些问题。我已尝试解决此问题,但无法得出结论。

这是数据:

# Import data
df_views = pd.read_excel('PageViews.xlsx')

# Check data types
df_views.dtypes
Out[57]:
Date           object
Customer ID     int64
dtype: object

日期列未按预期采用“日期时间”数据格式。进一步检查结果:

df_views.ix[:5]
Date    Customer ID
0   01/25/2016  104064596300
1   02/28/2015  102077474472
2   11/17/2016  106430081724
3   02/24/2016  107770391692
4   10/05/2016  106523680888
5   02/24/2016  107057691592

我快速检查哪些行没有遵循正确的格式 xx/xx/xxxx

print (df_views[df_views["Date"].str.len() != 10])
          Date   Customer ID
189513  12/14/  106285770688
189514  10/28/  107520462840
189515  11/01/  102969804360
189516  11/10/  102106417100
189517  02/16/  107810168068
189518  10/25/  102096164504
189519  02/08/  107391760644
189520  02/29/  107353558928
189521  10/24/  107209142140
189522  12/20/  107875461336
189523  12/23/  107736375428
189524  11/12/  106561080372
189525  01/27/  102676548120
189526  11/19/  107733043896
189527  12/31/  107774452412
189528  01/21/  102610956040
189529  01/09/  108052836888
189530  02/21/  106380330112
189531  02/02/  107844459772
189532  12/12/  102006641640
189533  12/16/  106604647688
189534  11/14/  102383102504

我试图创建一个 for 循环,但不知道如何处理我的循环。

重要提示:我知道所有观察的时间段都在 2015 年 9 月到 2016 年 2 月之间。

因此,如果月份是 09/10/11/12 - 那么我可以在日期中添加“2015”, 否则,如果月份是 01/02,我可以添加“2016”。

for row in df_views["Date"]:
    if len(row) != 10:
        if row.str.contains("^09|10|11|12\/"):
            row.str.cat("2015")
        elif row.str.contains("^01|02\/"):
            row.str.cat("2016")
    else:
        continue 
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-87-684e121dd62d> in <module>()
      5 for row in df_views["Date"]:
      6     if len(row) != 10:
----> 7         if row.str.contains("^09|10|11|12\/"):
      8             row.str.cat("2015")
      9         elif row.str.contains("^01|02\/"):

AttributeError: 'str' object has no attribute 'str'

【问题讨论】:

row 似乎是一个字符串。因此,您尝试的所有方法(包含、cat)都不太可能奏效。 避免使用 for 循环。只需直接使用您在系列上使用的.str 操作即可。您可能需要调整它们,但它会比显式迭代更快。 【参考方案1】:

作为@BrenBam has already written in the comment - 尽量避免使用循环。 Pandas 为我们提供了大量的矢量化(读取快速且高效)方法:

In [67]: df
Out[67]:
          Date   Customer ID
0   12/14/2001  106285770688
1   10/28/2000  107520462840
2       11/01/  102969804360
3       11/10/  102106417100
4       02/16/  107810168068
5       10/25/  102096164504
6       02/08/  107391760644
7       02/29/  107353558928
8       10/24/  107209142140
9       12/20/  107875461336
10      12/23/  107736375428
11      11/12/  106561080372
12      01/27/  102676548120
13      11/19/  107733043896
14      12/31/  107774452412
15      01/21/  102610956040
16      01/09/  108052836888
17      02/21/  106380330112
18      02/02/  107844459772
19      12/12/  102006641640
20      12/16/  106604647688
21      11/14/  102383102504

In [68]: df.ix[df.Date.str.match(r'^(?:09|10|11|12)\/\d2\/$', as_indexer=True), 'Date'] += '2015'

In [69]: df.ix[df.Date.str.match(r'^(?:01|02)\/\d2\/$', as_indexer=True), 'Date'] += '2016'

In [70]: df
Out[70]:
          Date   Customer ID
0   12/14/2001  106285770688
1   10/28/2000  107520462840
2   11/01/2015  102969804360
3   11/10/2015  102106417100
4   02/16/2016  107810168068
5   10/25/2015  102096164504
6   02/08/2016  107391760644
7   02/29/2016  107353558928
8   10/24/2015  107209142140
9   12/20/2015  107875461336
10  12/23/2015  107736375428
11  11/12/2015  106561080372
12  01/27/2016  102676548120
13  11/19/2015  107733043896
14  12/31/2015  107774452412
15  01/21/2016  102610956040
16  01/09/2016  108052836888
17  02/21/2016  106380330112
18  02/02/2016  107844459772
19  12/12/2015  102006641640
20  12/16/2015  106604647688
21  11/14/2015  102383102504

【讨论】:

解决方案有效,但最终在没有问题的情况下将“2015”或“2016”添加到数据框的其余部分。这个正则表达式对我有用:'^(09|10|11|12)\/\d\d\/$'

以上是关于在 Pandas 数据框中运行正则表达式循环的主要内容,如果未能解决你的问题,请参考以下文章

使用正则表达式从 pandas 数据框中提取元素

用正则表达式替换 Pandas 数据框中字符串的某个部分

在熊猫数据框中使用正则表达式替换列值

在 Pandas str.contains() 的正则表达式中使用变量

从 pandas 数据框列中查找所有正则表达式匹配项

Pandas 中的严格正则表达式替换