从Python中的数据框创建正则表达式匹配列表,然后计算匹配数

时间:2018-01-17 22:09:26

标签: python regex pandas dataframe

我正在尝试

匹配数据框中一列中出现的美元/分/百分比的次数 - 创建列出所有这些匹配项的函数 - 创建一个计算匹配数的函数

我能够成功使用正则表达式来查找匹配项,但我无法获得列表并计算它们。我尝试使用str.extract()列出所有匹配项,并str.contains().sum()计算匹配项数。但是,我无法让这些同时工作,我不确定这是否是正确的方法。

这是我到目前为止所拥有的:

(?:^|\s)(\$?(?:\d[ ,.]?)+%?)(?=\s|$) 

这将匹配任何美元/分或百分比,并解释我试图包含的一堆不同的拼写错误,因此正则表达式字符串很好。

import re
import pandas as pd

sample_csv = pd.DataFrame({'SMS_text': ['$1', '214-233-4455'],
                           'SMS_number': ['1', '1'],
                           'Amount': ['12.12%', '$10.12'],
                           'Percent': ['10%', '1']})

sample_csv.Amount.str.extract(r'(\$?(?:\d[ ,.]?)+%?)(?=\s|$)')

这将列出Amount列中的匹配项。

0    12.12%
1    $10.12
Name: Amount, dtype: object

如果我用str.extract()代替sample_csv.Amount.str.contains(r'(\$?(?:\d[ ,.]?)+%?)(?=\s|$)').sum(),它会告诉我有多少匹配(即2),但同样,我无法让它们同时工作。

这是正确的做法还是我设置错了?似乎可能findall()或者re.compile()可能效果更好,但我不确定如何让它们正常工作。

我从上面得到的输出结果如下:

regex_number_matches = ['12.12%', '$10.12']
regex_number_matches_count = 2

2 个答案:

答案 0 :(得分:1)

如果您想要在数据框中显示%或$的总次数,请尝试

sample_csv.stack().str.contains('%|\$').sum()

它返回4

如果您想要出现这些单元格的所有实例,请尝试

sample_csv[sample_csv.stack().str.contains('%|\$').unstack()]

你得到了

    Amount  Percent SMS_number  SMS_text
0   12.12%  10%     NaN         $1
1   $10.12  NaN     NaN         NaN

答案 1 :(得分:1)

似乎(对我而言)您希望在Amount列中找到无法转换为数字的值:

假设你有以下DF:

In [107]: sample_csv
Out[107]:
   Amount Percent  SMS_number      SMS_text
0  12.12%     10%           1            $1
1  $10.12       1           1  214-233-4455
2    1.23       2           1  214-233-4455
3    33,5       3           1  214-233-4455

首先创建这些行的布尔掩码,其中Amount不能转换为数值:

In [108]: mask = pd.to_numeric(sample_csv['Amount'], errors='coerce').isnull()

In [109]: mask
Out[109]:
0     True
1     True
2    False
3     True
Name: Amount, dtype: bool

现在您可以使用此蒙版轻松过滤DF:

In [110]: sample_csv.loc[mask, 'Amount']
Out[110]:
0    12.12%
1    $10.12
3      33,5
Name: Amount, dtype: object

In [111]: sample_csv.loc[mask, 'Amount'].tolist()
Out[111]: ['12.12%', '$10.12', '33,5']

In [112]: len(sample_csv.loc[mask, 'Amount'])
Out[112]: 3