pandas从字符串中找到所有精确的4个连续数字



我有一个包含文本模式的大文本文件,我从该文件中创建一个pandas数据框架,如下所示,从这个模式列中我想选择一个包含数字的模式,并且连续数字的长度正好是4.

例如a1234bc5678,我们可以从中得到两个新的4位数模式,例如:12345678a12345不被接受,因为连续数字的长度是5, not4.

print (df.sample(20))
pattern
13457358     187019980
9892646         920204
2258941        dong998
5792706     diao511001
9144372       a2805938
15519502       YUEH008
15831448     752099429
15659305     469919209
13769825      majunsui
3446320       sishenD2
12970622     woaini123
11633295      guswjddl
12708217  342423198706
2079106     zj87755202
12551254   mxt19950626
4572063        1985625
7805173     theend0512
484820      jzm5583385
15017582       1981122
10868176      30061984

我试过了:这是一个为我产生错误输出的单个字符串,因为我只想要精确的4个连续数字. 此外,如果我能完成的话,我需要在pandas数据框架上完成它。

text = '1234sunwei198734'
postcodes = re.findall('d{4}',text)
print(postcodes)

最后我这样做了,

df2['pins'] = df2['pattern'].apply(lambda x: re.findall('(?<!d)d{4}(?!d)',x))
df3 = df2[df2['pins'].apply(lambda x: len(x)) > 0]

在您的描述之后,您可能正在寻找

(?<!d)d{4}(?!d)

参见regex101.com的演示.

我认为这个任务最好的正则表达式是

(?<!d)(1234|2345|3456|4567|5678|6789|7890|8901|9012|0123)(?!d)

当然你可以删除你不想要的

如果你不想明确地说明4个连续数字的模式,你可以使用不太有效的方法,如:

  • 查找所有4个字母的数字字符串,例如D(d{4})D
  • 检查是否连续

虽然正则表达式已经给出,但回答您的评论与熊猫栏..

来自你的帖子的样本数据集:

>>> df1
pattern
0      187019980
1         920204
2        dong998
3     diao511001
4       a2805938
5        YUEH008
6      752099429
7      469919209
8       majunsui
9       sishenD2
10     woaini123
11      guswjddl
12  342423198706
13    zj87755202
14   mxt19950626
15       1985625
16    theend0512
17    jzm5583385
18       1981122
19      30061984

将正则表达式应用于pandas列(即pattern),您可以使用下面的语法,它基本上返回一个列表对象,如:

>>> df1['pattern'].str.findall(r'(?<!d)d{4}(?!d)')
0         []
1         []
2         []
3         []
4         []
5         []
6         []
7         []
8         []
9         []
10        []
11        []
12        []
13        []
14        []
15        []
16    [0512]    <-- this is your matched pattern
17        []
18        []
19        []
Name: pattern, dtype: object

因此,您可以将这些空列表对象转换为字符串,这将成为NaN然后删除所有它们,因为您只需要匹配值..

>>> df1['pattern'].str.findall(r'(?<!d)d{4}(?!d)').str[0].dropna()
#  df1['pattern'].str.extract(r'((?<!d)+d{4})+(?!d)').dropna()
16    0512

你的文章的最后一点更好的方法:

只是为了您需要的更好的解决方案,并通过导入re模块来完成您的方法,这不是必需的,您可以简单地这样做。虽然选择权在你:-)..

>>> df1['pins'] = df1['pattern'].str.findall(r'(?<!d)d{4}(?!d)')
>>> df1[df1['pins'].apply(lambda x: len(x)) > 0]
pattern    pins
16  theend0512  [0512]

相关内容

最新更新