我有一个 Pandas 数据框,如下所示:
textID1, text1, othermetadata1
textID2, text2, othermetadata2
textID3, text3, othermetadata3
我想在一个新的数据框中将文本分成句子,如下所示:
textID1-001, sentence1 (of text1), othermetadata1
textID1-002, sentence2 (of text1), othermetadata1
textID2-001, sentence1 (of text2), othermetadata2
我知道如何使用 NLTK 或 spaCy 将文本分成句子,例如:
sentences = [ sent_tokenize(text) for text in texts ]
但是 pandas 仍然让我感到困惑:如何获取输出并将其打包回数据框中?此外,如何将数字添加到现有列或创建一个新列以重新开始对每个文本进行编号 - 我的假设是我可以随后合并 textID 和 sentenceID 列?
一旦获得给定行的句子列表,您可以使用 explode() 将它们分成单独的行。分解行会维护原始 DF 的索引,并使用 cumcount(),您可以为原始行生成连续的 ID。
这里我假设您的文本 ID 列称为“text_id”,句子列称为“sentences”。
df = df.explode(['sentences']).reset_index().rename(columns={'index' : 'row_id'})
df['row_id'] = df.groupby('row_id').cumcount()
如果您想将文本 ID 列与 row_id 合并,您可以使用以下内容:
df['text_id'] = df['text_id'] + "-" + df["row_id"]
上述问题的完整解决方案:
import nltk
nltk.download('punkt')
from nltk.tokenize import sent_tokenize
df = pd.DataFrame([["textID1", "text1 sentence1. text1 sentence2", "othermetadata1"],
["textID2", "text2 sentence1", "othermetadata2"],
["textID3", "text3 sentence1. text3 sentence2. text3 sentence3", "othermetadata3"]], columns=["text_id", "text", "metadata"])
df['text'] = df['text'].apply(sent_tokenize)
df = df.explode("text").reset_index().rename(columns={'index' : 'row_id'})
df['row_id'] = df.groupby('row_id').cumcount()
df['text_id'] = df['text_id'] + "-" + df["row_id"].astype('str')
df = df.drop(columns=['row_id'])
df
text_id text metadata
0 textID1-0 text1 sentence1. othermetadata1
1 textID1-1 text1 sentence2 othermetadata1
2 textID2-0 text2 sentence1 othermetadata2
3 textID3-0 text3 sentence1. othermetadata3
4 textID3-1 text3 sentence2. othermetadata3
5 textID3-2 text3 sentence3 othermetadata3