【问题标题】:Pandas Removing Text Before and After Certain Characters熊猫在某些字符之前和之后删除文本
【发布时间】:2018-08-22 00:05:13
【问题描述】:

我不确定我的头衔是否很棒,所以如果有人有建议,我会接受。

假设我有以下场景:

搜索“哪里”

输入:

<Dave likes cake.> <Dave goes to school.> <Where is dave today, after school?/><I do not know where dave is>
<Cindy reads a book><Where is my shoe asked cindy.><Cindy likes bacon.><Cindy goes to the park.><where did cindy go?>
<Sally drinks wine.><The lake is where I am from commented Sally><Cindy watches day time television while watching the kids.><Cindy makes great sandwiches><where is the sandwich cindy made?>

期望的输出:

<Where is dave today, after school?/><I do not know where dave is>
<Where is my shoe asked cindy.><where did cindy go?>
<The lake is where I am from commented Sally><where is the sandwich cindy made?>

我想保留从包含我正在搜索的短语的另一组字符中的第一个字符开始的所有内容。

我还想删除包含我要查找的短语的第一个字符之前的所有内容,以及删除包含该短语的最后一个字符之后的所有内容。

有什么建议吗?我不确定如何解决这个问题,但我正在考虑使用某种正则表达式,可能会向前/向后看?

编辑#1:上下文添加到我正在做的事情中

这与熊猫有关,因为我将 XML 文件作为文本存储在熊猫数据框内。 XML 文件是一个 SSIS 包,我需要它来搜索特定的单词和短语。

我做了一个连接来将所有的 xml 连接成 1 行。

编辑#2:更多上下文

我在查看的 XML 数据中遇到了多行 SQL 语句的问题,这就是我在 1 行中使用 ' '.join 的原因。

如果我要查找的是多行 SQL 语句的一部分,我不仅需要找到 XML 中的位置,还需要返回所有 SQL 语句。

编辑#3:

这个解决方案(由下面的另一个用户提供)解决了这个问题,但它只返回第一个实例。如果有人有返回所有实例的解决方案,我会将答案标记为已解决。

有效但只返回第一个实例的解决方案:

df.text.str.extract(r'(?i)(<[^<]*?where[^>]*?>)')

                                               0
0          <Where is dave today, after school?/>
1                <Where is my shoe asked cindy.>
2  <The lake is where I am from commented Sally>

编辑#4:返回所有匹配项

提供我的解决方案的用户提到使用findall 而不是extract 来返回所有行。

现在已经 100% 解决了。

【问题讨论】:

  • 好奇这与熊猫有什么关系?
  • 我编辑了我的帖子以添加上下文
  • 与其将它们合并成一行,不如将每一行存储在数据框的一列中,然后利用df['My Lines'].str.contains('where')
  • 编辑了我的帖子以添加更多上下文,这有意义吗?

标签: python python-3.x pandas


【解决方案1】:

使用str.extract:

df.text.str.extract(r'(?i)(<[^<]*?where[^>]*?>)')

                                               0
0          <Where is dave today, after school?/>
1                <Where is my shoe asked cindy.>
2  <The lake is where I am from commented Sally>

正则表达式解释:

(?i)                        # Case insensitive matching
(                           # Start of matching group
  <                         # matches the < character
  [^<]                      # matches anything that's *not* <
  *?                        # matches zero-unlimited times
  where                     # matches the substring where
  [^>]                      # matches anything that's *not* >
  *?                        # matches zero-unlimited times
  >                         # matches >
)                           # end of matching group

【讨论】:

  • 我创建了这个数据框来测试:df2 = pd.DataFrame([''], columns=['A']) 然后我输入了这个: df2.A.str.extract(r'(?i)(]^?>)') 错误信息返回的是 re.error: nothing to repeat at position 22
  • 当我使用那个数据框时,我得到&lt;Where is dave today, after school?/&gt;
  • 好的,继续测试。
  • 这只会找到第一次出现。使用findall 查找所有匹配项
  • 这太完美了!
【解决方案2】:

解决方案可能如下:

import re

a ='<Dave likes cake.> <Dave goes to school.> <Where is dave today, after school?/>'
b ='<Cindy reads a book><Where is my shoe asked cindy.><Cindy likes bacon.><Cindy goes to the park.>'
def find_where(str):
    mylist =str.split('<')
    r = re.compile(".*[W,w]here")
    newlist = list(filter(r.match, mylist)) # Read Note
    finallist = ['<'+x for x in newlist]
    return finallist[0]

如果您随后将该函数应用于您的字符串之一:

new_a = find_where(a)

并打印你的结果,你得到你的输出:

'<Where is dave today, after school?/>'

假设您发布的字符串是数据框列的元素(正如您的标题所暗示的那样),您可以照此进行,以应用于您的数据框:

df.mycolumn = df.mycolumn.apply(find_where)

【讨论】:

  • 感谢您的帮助,现在正在试验。完成实验后会更新。
  • 我决定使用另一个答案,因为它更简单。谢谢你的尝试,我赞成你的帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多