Pandas 将文本切片到新列,开始和结束位置由正则表达式表示
Pandas slice text to new column with start stop location denoted by regular expression
感谢您帮助解决这个问题。我还是 python 的新手,但知道 VBA excel。
在正则表达式条件下将开始和停止位置提取到数据框中的新列时,返回整数并且没有问题。但是当尝试使用该代码对文本进行切片时,出现以下错误
TypeError: 切片索引必须是整数或 None 或具有 index 方法
我有以下数据框数据行和代码行,这是我在过去几天尝试了许多不同的变体后尝试过的。我觉得这是我最接近解决它的一次。
|MENU_HINT |StartPos |EndPos
|AUS / Maitland (AUS) 28th Feb |4 |22
df2['StartPos'] = df2["MENU_HINT"].str.find('/')
df2['EndPos'] = df2["MENU_HINT"].apply(lambda x: re.search('d+', x).start() if re.search('\d+', x) else re.search('\d+', x)) + 1
df2['Track'] = df2['MENU_HINT'].apply(lambda x: x[x.find('/ ') + 1:df2['EndPos']])
我希望提取从“/”开始的位置名称,并将日期排除到 MENU_HINT 列的新列中。
我什至尝试了下面的代码,我发现它也以整数形式提供了结束位置。但是,当尝试使用列或自己为切片编码时,它仍然会提供相同的错误
df2['Track3'] = df2["MENU_HINT"].apply(lambda x: re.search(
'\d+', x).start() if re.search('\d+', x) else re.search('\d+', x)) + 1
我正在尝试查找第一个数字,因为该字段只有一个我想截断的日期。
我仍处于学习模式,但可以很好地理解概念,所以我想了解为什么会发生这种情况,因为它对我来说似乎是一个有用的知识库,因为我会遇到这种类型的提取经常。
感谢您花时间和精力帮助我解决这个问题。
真诚的,
保罗
这一行的问题:
df2['Track'] = df2['MENU_HINT'].apply(lambda x: x[x.find('/ ') + 1:df2['EndPos']])
是您将函数应用于列 MENU_HINT,哪些行将在 lambda 函数中称为 x,然后在函数内部获取 df2['EndPos'],这将return a 整列不只是一个整数,因此不能用于索引。要对此进行编辑,您可以将该函数应用于行,如下所示:
df['Track3'] = df.apply(lambda x: x["MENU_HINT"][x["MENU_HINT"].find('/ ') + 1:x['EndPos']], axis=1)
请注意,我将 axis=1 传递给 apply 函数,这会将函数应用于 DataFrame 的整行,让我可以访问其中的任何一行。
另一种方法是直接使用正则表达式来提取您想要的部分,如下所示:
df['Track3'] = df["MENU_HINT"].apply(lambda x:re.search(r"[A-Za-z]+ / ([A-Za-z | ( | )]+)", x).group(1))
在这里,我要搜索以字母字符开头,后跟斜杠,然后再是字母字符或圆括号的字符串。其输出如下所示:
MENU_HINT Track
AUS / Maitland (AUS) 28th Feb Maitland (AUS)
如果您希望使函数长于一行(因为 lambda 函数在某些情况下会有所限制),这将使对字符串的操作更加清晰和注释,那么您可以这样做:
import pandas as pd
# sample data for dataframe
d = {'menu_hint':['AUS / Maitland (AUS) 28th Feb']}
df = pd.DataFrame(d)
print('the old dataframe:')
print(df)
def strip_word(s:str):
''' function to strip parts of word '''
# n is the start position
n = s.find('/')
n = n+2 # adjust for spaces
# m is the end position
m = s.find(') ')
m = m+1 # adjust for zero index
s_new = s[n:m]
return s_new
df['Track3'] = df['menu_hint'].apply(strip_word)
print('the new dataframe:')
print(df)
输出:
menu_hint
0 AUS / Maitland (AUS) 28th Feb
the new dataframe:
menu_hint Track3
0 AUS / Maitland (AUS) 28th Feb Maitland (AUS)
感谢您帮助解决这个问题。我还是 python 的新手,但知道 VBA excel。
在正则表达式条件下将开始和停止位置提取到数据框中的新列时,返回整数并且没有问题。但是当尝试使用该代码对文本进行切片时,出现以下错误
TypeError: 切片索引必须是整数或 None 或具有 index 方法
我有以下数据框数据行和代码行,这是我在过去几天尝试了许多不同的变体后尝试过的。我觉得这是我最接近解决它的一次。
|MENU_HINT |StartPos |EndPos
|AUS / Maitland (AUS) 28th Feb |4 |22
df2['StartPos'] = df2["MENU_HINT"].str.find('/')
df2['EndPos'] = df2["MENU_HINT"].apply(lambda x: re.search('d+', x).start() if re.search('\d+', x) else re.search('\d+', x)) + 1
df2['Track'] = df2['MENU_HINT'].apply(lambda x: x[x.find('/ ') + 1:df2['EndPos']])
我希望提取从“/”开始的位置名称,并将日期排除到 MENU_HINT 列的新列中。
我什至尝试了下面的代码,我发现它也以整数形式提供了结束位置。但是,当尝试使用列或自己为切片编码时,它仍然会提供相同的错误
df2['Track3'] = df2["MENU_HINT"].apply(lambda x: re.search(
'\d+', x).start() if re.search('\d+', x) else re.search('\d+', x)) + 1
我正在尝试查找第一个数字,因为该字段只有一个我想截断的日期。
我仍处于学习模式,但可以很好地理解概念,所以我想了解为什么会发生这种情况,因为它对我来说似乎是一个有用的知识库,因为我会遇到这种类型的提取经常。
感谢您花时间和精力帮助我解决这个问题。
真诚的, 保罗
这一行的问题:
df2['Track'] = df2['MENU_HINT'].apply(lambda x: x[x.find('/ ') + 1:df2['EndPos']])
是您将函数应用于列 MENU_HINT,哪些行将在 lambda 函数中称为 x,然后在函数内部获取 df2['EndPos'],这将return a 整列不只是一个整数,因此不能用于索引。要对此进行编辑,您可以将该函数应用于行,如下所示:
df['Track3'] = df.apply(lambda x: x["MENU_HINT"][x["MENU_HINT"].find('/ ') + 1:x['EndPos']], axis=1)
请注意,我将 axis=1 传递给 apply 函数,这会将函数应用于 DataFrame 的整行,让我可以访问其中的任何一行。
另一种方法是直接使用正则表达式来提取您想要的部分,如下所示:
df['Track3'] = df["MENU_HINT"].apply(lambda x:re.search(r"[A-Za-z]+ / ([A-Za-z | ( | )]+)", x).group(1))
在这里,我要搜索以字母字符开头,后跟斜杠,然后再是字母字符或圆括号的字符串。其输出如下所示:
MENU_HINT Track
AUS / Maitland (AUS) 28th Feb Maitland (AUS)
如果您希望使函数长于一行(因为 lambda 函数在某些情况下会有所限制),这将使对字符串的操作更加清晰和注释,那么您可以这样做:
import pandas as pd
# sample data for dataframe
d = {'menu_hint':['AUS / Maitland (AUS) 28th Feb']}
df = pd.DataFrame(d)
print('the old dataframe:')
print(df)
def strip_word(s:str):
''' function to strip parts of word '''
# n is the start position
n = s.find('/')
n = n+2 # adjust for spaces
# m is the end position
m = s.find(') ')
m = m+1 # adjust for zero index
s_new = s[n:m]
return s_new
df['Track3'] = df['menu_hint'].apply(strip_word)
print('the new dataframe:')
print(df)
输出:
menu_hint
0 AUS / Maitland (AUS) 28th Feb
the new dataframe:
menu_hint Track3
0 AUS / Maitland (AUS) 28th Feb Maitland (AUS)