如何在 pandas 中提取另一个词之前的一个词
How to extract a word before another word in pandas
我有这个 pandas DataFrame,它描述了一场足球比赛中的比赛:
play_id
type
Text
1
pass
Jon pass complete to Ben.
2
pass
Clock 14:52, Jon pass complete to Mitch.
3
rush
Frank rush.
我的 objective 是创建一个名为“passer”的新列,其中包含一个脚本,该脚本将遍历“text”列中的描述,并将采用单词 [= 之前的名称34=]。所以我首先使用了这个:
df['passer'] = df['Text'].str.extract(r'(.*?)pass', expand=False).str.strip()
这给了我这个:
play_id
type
Text
passer
1
pass
Jon pass complete to Ben.
Jon
2
pass
Clock 14:52, Jon pass complete to Mitch.
Clock 14:52, Jon
3
rush
Frank rush.
NaN
它适用于第一个和第三个 playid,但不适用于第二个,因为它需要时钟,有时可以包含在描述中。
我尝试在创建我的专栏时实施条件,其中代码检查描述中是否包含 'Clock',并使用正确的正则表达式,但这不起作用:
conditions = [
(np.where(df.Text.str.contains('Clock', case=False))),
(np.where(~df.Text.str.contains('Clock', case=False)))
]
choices = [
df['Text'].str.extract(r', (.*?) pass', expand=False).str.strip(),
df['Text'].str.extract('(.*?) pass', expand=False).str.strip()
]
df['passerNEW'] = np.select(conditions, choices, default='NaN')
df
我收到以下错误:
TypeError: invalid entry 0 in condlist: should be boolean ndarray
有没有办法让这个功能发挥作用?这似乎是一个很好的方法,因为在其他情况下,我可以检查三个不同的条件,以便知道要使用哪个正则表达式。
尝试使用 (?=)
正向前瞻,一种 zero-width assertion。因此,代码将如下所示:
df['passer'] = df['Text'].str.extract(r'(\w+)(?=\spass)', expand=False)
输出:
| play_id | type | Text | passer |
| -------- | ----- | ---------------------------------------- | ------ |
| 1 | pass | Jon pass complete to Ben. | Jon |
| 2 | pass | Clock 14:52, Jon pass complete to Mitch. | Jon |
| 3 | rush | Frank rush. | NaN |
- 将
pandas.Series.str.extract
与正先行条件一起使用。
- 有关
lookahead
的详尽解释,请参阅 SO: Regex lookahead, lookbehind and atomic groups。
\s+pass
适用于名称和 'pass'
之间的任意数量的空格(例如 'Jon PaSs'
)
flags=re.IGNORECASE
用于忽略'pass'
的大小写
可以使用 df.Text.str.lower().str.extract('(\w+(?=\s+pass))')
而不是为标志导入 re
。
import pandas as pd
import re
# test dataframe
data = {'play_id': ['1', '2', '3'], 'type': ['pass', 'pass', 'rush'], 'Text': ['Jon PASS complete to Ben.', 'Clock 14:52, Jon pass complete to Mitch.', 'Frank rush.']}
df = pd.DataFrame(data)
# display(df)
play_id type Text
1 pass Jon PASS complete to Ben.
2 pass Clock 14:52, Jon pass complete to Mitch.
3 rush Frank rush.
# extract
df['passer'] = df.Text.str.extract('(\w+(?=\s+pass))', flags=re.IGNORECASE)
# display(df)
play_id type Text passer
1 pass Jon PASS complete to Ben. Jon
2 pass Clock 14:52, Jon pass complete to Mitch. Jon
3 rush Frank rush. NaN
我有这个 pandas DataFrame,它描述了一场足球比赛中的比赛:
play_id | type | Text |
---|---|---|
1 | pass | Jon pass complete to Ben. |
2 | pass | Clock 14:52, Jon pass complete to Mitch. |
3 | rush | Frank rush. |
我的 objective 是创建一个名为“passer”的新列,其中包含一个脚本,该脚本将遍历“text”列中的描述,并将采用单词 [= 之前的名称34=]。所以我首先使用了这个:
df['passer'] = df['Text'].str.extract(r'(.*?)pass', expand=False).str.strip()
这给了我这个:
play_id | type | Text | passer |
---|---|---|---|
1 | pass | Jon pass complete to Ben. | Jon |
2 | pass | Clock 14:52, Jon pass complete to Mitch. | Clock 14:52, Jon |
3 | rush | Frank rush. | NaN |
它适用于第一个和第三个 playid,但不适用于第二个,因为它需要时钟,有时可以包含在描述中。
我尝试在创建我的专栏时实施条件,其中代码检查描述中是否包含 'Clock',并使用正确的正则表达式,但这不起作用:
conditions = [
(np.where(df.Text.str.contains('Clock', case=False))),
(np.where(~df.Text.str.contains('Clock', case=False)))
]
choices = [
df['Text'].str.extract(r', (.*?) pass', expand=False).str.strip(),
df['Text'].str.extract('(.*?) pass', expand=False).str.strip()
]
df['passerNEW'] = np.select(conditions, choices, default='NaN')
df
我收到以下错误:
TypeError: invalid entry 0 in condlist: should be boolean ndarray
有没有办法让这个功能发挥作用?这似乎是一个很好的方法,因为在其他情况下,我可以检查三个不同的条件,以便知道要使用哪个正则表达式。
尝试使用 (?=)
正向前瞻,一种 zero-width assertion。因此,代码将如下所示:
df['passer'] = df['Text'].str.extract(r'(\w+)(?=\spass)', expand=False)
输出:
| play_id | type | Text | passer |
| -------- | ----- | ---------------------------------------- | ------ |
| 1 | pass | Jon pass complete to Ben. | Jon |
| 2 | pass | Clock 14:52, Jon pass complete to Mitch. | Jon |
| 3 | rush | Frank rush. | NaN |
- 将
pandas.Series.str.extract
与正先行条件一起使用。- 有关
lookahead
的详尽解释,请参阅 SO: Regex lookahead, lookbehind and atomic groups。 \s+pass
适用于名称和'pass'
之间的任意数量的空格(例如'Jon PaSs'
)
- 有关
flags=re.IGNORECASE
用于忽略'pass'
的大小写-
可以使用
df.Text.str.lower().str.extract('(\w+(?=\s+pass))')
而不是为标志导入re
。
import pandas as pd
import re
# test dataframe
data = {'play_id': ['1', '2', '3'], 'type': ['pass', 'pass', 'rush'], 'Text': ['Jon PASS complete to Ben.', 'Clock 14:52, Jon pass complete to Mitch.', 'Frank rush.']}
df = pd.DataFrame(data)
# display(df)
play_id type Text
1 pass Jon PASS complete to Ben.
2 pass Clock 14:52, Jon pass complete to Mitch.
3 rush Frank rush.
# extract
df['passer'] = df.Text.str.extract('(\w+(?=\s+pass))', flags=re.IGNORECASE)
# display(df)
play_id type Text passer
1 pass Jon PASS complete to Ben. Jon
2 pass Clock 14:52, Jon pass complete to Mitch. Jon
3 rush Frank rush. NaN