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

2024-05-16 19:19:45 发布

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

我有一个包含文本模式的大文本文件,从该文件中我制作了一个熊猫数据框,如下所示,从这个模式列中我想选择一个包含数字的模式,连续数字的长度正好是4

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

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个连续数字。另外,如果我能完成的话,我需要在熊猫数据框上完成

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]

Tags: 数据lambdatext文本re模式数字pattern
3条回答

虽然已经给出了正则表达式,但在熊猫专栏中回答您的评论

文章中的示例数据集:

>>> 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

将regex应用于pandas列iepattern这里,您可以使用下面的语法,该语法基本上返回如下所示的列表对象

>>> 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]

根据您的描述,您可能正在寻找

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

a demo on regex101.com

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

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

当然,你可以删除你不想要的东西

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

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

相关问题 更多 >