Python 提取括号之间的文本,并为每一位文本创建行
在熊猫数据框中,我需要提取方括号之间的文本,并将该文本作为新列输出。我需要在“StudyID”级别执行此操作,并为提取的每一位文本创建新行 下面是一个简化的数据帧示例Python 提取括号之间的文本,并为每一位文本创建行,python,pandas,dataframe,Python,Pandas,Dataframe,在熊猫数据框中,我需要提取方括号之间的文本,并将该文本作为新列输出。我需要在“StudyID”级别执行此操作,并为提取的每一位文本创建新行 下面是一个简化的数据帧示例 data = { "studyid":['101', '101', '102', '103'], "Question":["Q1",
data = {
"studyid":['101',
'101',
'102',
'103'],
"Question":["Q1",
"Q2",
"Q1",
"Q3"],
"text":['I love [Bananas] and also [oranges], and [figs]',
'Yesterday I ate [Apples]',
'[Grapes] are my favorite fruit',
'[Mandarins] taste like [oranges] to me'],
}
df2 = pd.DataFrame(data)
我制定了一个解决方案(请参阅下面的代码,如果您运行它,它将显示所需的输出),但是它非常长,需要很多步骤。我想知道是否有一个更短的方法来做这件事
您将看到,我在正则表达式中使用了str.findall(),但我最初尝试了str.extractall(),它将提取的文本输出到数据帧,但我不知道如何使用extractall()生成的数据帧中包含的“studyid”和“question”列输出提取的文本。所以我求助于使用str.findall()
这是我的代码(‘我知道它很笨重’)-如何减少步骤数?提前感谢您的帮助
# Step 1: Use Regex to pull out the text between the square brackets
df3 = pd.DataFrame(df2['text'].str.findall(r"(?<=\[)([^]]+)(?=\])").tolist())
# Step 2: Merge the extracted text back with the original data
df3 = df2.merge(df3, left_index=True, right_index=True)
# Step 3: Transpose the wide file to a long file (e.g. panel)
df4 = pd.melt(df3, id_vars=['studyid', 'Question'], value_vars=[0, 1, 2])
# Step 4: Delete rows with None in the value column
indexNames = df4[df4['value'].isnull()].index
df4.drop(indexNames , inplace=True)
# Step 5: Sort the data by the StudyID and Question
df4.sort_values(by=['studyid', 'Question'], inplace=True)
# Step 6: Drop unwanted columns
df4.drop(['variable'], axis=1, inplace=True)
# Step 7: Reset the index and drop the old index
df4.reset_index(drop=True, inplace=True)
df4
#步骤1:使用Regex拉出方括号之间的文本
df3=pd.DataFrame(df2['text'].str.findall(r“(?如果可以使用向列分配后输出,则最后一个for unique索引与drop=True
一起使用):
df2['text'] = df2['text'].str.findall(r"(?<=\[)([^]]+)(?=\])")
df4 = df2.explode('text').reset_index(drop=True)
您可以将代码“压缩”为单个指令:
df2[['studyid', 'Question']].join(df2['text'].str.findall(
r'\[([^]]+)\]').explode().rename('value'))
甚至正则表达式也可以简化:不需要lookback/lookforward。
只需在捕获组之前/之后放置两个括号
如果需要,请将此结果保存在变量下(例如df4=…)
注意:在您的解决方案中,您命名了最终结果(df4)中的最后一列
作为值,所以我在解决方案中重复了它。
但是,如果您想将此名称更改为您想要的任何名称,请替换“value”
在我的解决方案中使用您选择的另一个名称。非常感谢jezrael,这太棒了!str.extractall()解决方案正是我第一次使用此解决方案时所寻找的。我知道会有一个简单的解决方案!太棒了!感谢Valdi_Bo提供的另一个伟大的解决方案!
print (df4)
studyid Question text
0 101 Q1 Bananas
1 101 Q1 oranges
2 101 Q1 figs
3 101 Q2 Apples
4 102 Q1 Grapes
5 103 Q3 Mandarins
6 103 Q3 oranges
df2[['studyid', 'Question']].join(df2['text'].str.findall(
r'\[([^]]+)\]').explode().rename('value'))