将具有模式的元素保留在 pandas 系列中而不将它们转换为列表

Keep elements with pattern in pandas series without converting them to list

我有以下数据框:

df = pd.DataFrame(["Air type:1, Space kind:2, water", "something, Space blu:3, somethingelse"], columns = ['A'])

我想创建一个新列,其中每一行包含所有带有“:”的元素。因此,例如,在第一行中我想要 return "type:1, kind:2" 并且在第二行中我想要 "blu:3"。我通过以下方式使用列表理解来管理:

df['new'] = [[y for y in x  if ":" in y] for x in df['A'].str.split(",")]

但我的问题是新列包含列表元素。

    A                                                       new
0   Air type:1, Space kind:2, water                         [Air type:1, Space kind:2]
1   something at the start:4, Space blu:3, somethingelse    [something at the start:4, Space blu:3]

我没有经常使用 Python 所以我不能 100% 确定我是否缺少更 Pandas 具体的方法来做到这一点。如果有的话,很高兴了解它并使用它。 如果这是一种正确的方法,我怎样才能将元素转换回字符串以便对它们执行正则表达式?我尝试了 How to concatenate items in a list to a single string?,但这并没有像我希望的那样工作。

你可以在这里使用pd.Series.str.findall

df['new'] = df['A'].str.findall('\w+:\w+')

                                 A               new
0            type:1, kind:2, water  [type:1, kind:2]
1  something, blu:3, somethingelse           [blu:3]

编辑:

当有多个单词时再尝试

df['new'] = df['A'].str.findall('[^\s,][^:,]+:[^:,]+').str.join(', ')

                                      A                       new
0        Air type:1, Space kind:2, water  Air type:1, Space kind:2
1  something, Space blu:3, somethingelse               Space blu:3

您可以将 findalljoin 一起使用:

import pandas as pd
df = pd.DataFrame(["type:1, kind:2, water", "something, blu:3, somethingelse"], columns = ['A'])
df['new'] = df['A'].str.findall(r'[^\s:,]+:[^\s,]+').str.join(', ')
df['new']
# => 0    type:1, kind:2
# => 1             blu:3

正则表达式匹配

  • [^\s:,]+ - 除了白色 space、:,
  • 之外的一个或多个字符
  • : - 冒号
  • [^\s,]+ - 除了 whitespace 和 ,.
  • 之外的一个或多个字符

参见regex demo

.str.join(', ') 将找到的所有匹配项与 ,+space 连接起来。