【问题标题】:x.findall function returns a value but won't write to pandas data framex.findall 函数返回一个值,但不会写入 pandas 数据帧
【发布时间】:2015-12-04 17:11:49
【问题描述】:

我创建了一个搜索 NLTK.text.Text 对象的函数,并在我运行该函数时返回一个值。

更新:问题似乎是在下面的函数中,“捐赠”变量实际上并没有被传递一个值。然而,text.findall 函数确实返回了一个值,但由于某种原因没有更新变量。

def find_donation_orgs(x):
    text = nltk.Text(nltk.word_tokenize(x))
    donation =  text.findall(r"<\.> <.*>{,15}? <donat.*|contrib.*|Donat.*|Contrib.*> <.*>*? <to> (<.*>+?) <\.|\,|\;> ")
    return donation

以下输入的输出类似于此,但我认为输出来自 text.findall 而不是实际的“回报捐赠”。

a = "This is a sentence. I also donate to Mr. T's Tea Party. I contribute to the Boys and Girls club. "

find_donation_orgs(a)

输出 =

Mr. T 's Tea Party
the Boys and Girls club

但是,当我尝试应用该函数以将输出写入 pandas 数据框中的新列时,它返回 None。见下文:

df['donation_orgs'] = df.apply(lambda row: find_donation_orgs(row['Obit']), axis = 1)

其中 df['Obit'] 是一串文本,类似于我上面的 a 变量。

更新:所以看起来 text.findall 的输出并没有更新它分配给的变量的值......所以我需要弄清楚如何将该输出实际分配给一个变量以便返回它到一个数据框。见下文:

text = df.text.iloc[1]

textfindall = text.findall(r"<\.> <.*>{,15}? <donat.*|contrib.*|Donat.*|Contrib.*> <.*>*? <to> (<.*>+?) <\.|\,|\;> ")

print('text is ' + str(type(text)))
print('textfindall is ' + str(type(textfindall)))
print(textfindall)

输出:

visit brother Alfred Fuller; the research of Dr. Giuseppe Giaccone at
Georgetown University
text is <class 'nltk.text.Text'>
textfindall is <class 'NoneType'>
none

【问题讨论】:

  • df['donation_orgs'] = df['Obit'].apply(lambda x: find_donation_orgs(x), axis=1) ?
  • 该代码运行良好,并且确实创建了一个“donation_orgs”列,但仍然在该列的每一行中返回 None ......我认为这是我的函数总是返回 none 类型的某种问题对象,即使 text.findall 工作正常

标签: python pandas nlp dataframe nltk


【解决方案1】:

尝试通过检查函数实际接收和返回的内容来调试代码。您可以使用调试器(在大多数 IDE 中都可以找到)或使用函数的返回值来确保问题出在您的函数还是 pandas 函数

def find_donation_orgs(x):
    return x

确保您的输入符合您的预期。

def find_donation_orgs(x):
    return nltk.Text(nltk.word_tokenize(x))

看看标记化是怎么回事。

def find_donation_orgs(x):
    text = nltk.Text(nltk.word_tokenize(x))
    all_occurrences = text.findall(r"<\.> <.*>{,15}? <donat.*|contrib.*|Donat.*|Contrib.*> <.*>*? <to> (<.*>+?) <\.|\,|\;> ")
    if all_occurrences is None:
        return "no occurrences"
    else:
        return all_occurrences

检查您的正则表达式是否可能起作用。在这种情况下,请返回标记器输出以尝试修复您的正则表达式。

更新

查看source code of the nltk.Text 对象,看来findall 方法实际上并没有返回任何内容,而是打印了结果:

def findall(self, regexp):
    if "_token_searcher" not in self.__dict__:
        self._token_searcher = TokenSearcher(self)

    hits = self._token_searcher.findall(regexp)
    hits = [' '.join(h) for h in hits]
    print(tokenwrap(hits, "; "))

这是因为 Text 对象仅用于通过交互式控制台使用:

围绕一系列简单(字符串)标记的包装器,旨在支持文本的初始探索(通过交互式控制台)。 [...] 如果您想编写一个利用这些分析的程序,那么您应该绕过 Text 类,而直接使用适当的分析函数或类。

你的函数应该是这样的:

from nltk.util import tokenwrap
def find_donation_orgs(x):
    searcher = nltk.TokenSearcher(nltk.word_tokenize(x))
    hits = searcher.findall(r"<\.> <.*>{,15}? <donat.*|contrib.*|Donat.*|Contrib.*> <.*>*? <to> (<.*>+?) <\.|\,|\;> ")

    hits = [' '.join(h) for h in hits]
    donation = tokenwrap(hits, "; ")
    return donation

这会复制原始行为,但实际返回值除外。当然,您可能希望在收到hits 列表后以不同的方式格式化您的输出。

【讨论】:

  • 所以前两个输出正是我想要的。当我循环使用 for x in df['Obit']: find_donation_orgs(x)... 时,第三个也是但是,“contrib”或“donat”,当我将它们写入数据框时,每个实例都不会返回任何事件
  • 我查看了 nltk.Text().findall ,看来实际问题是该方法实际上没有返回任何内容,而只是打印结果。我会相应地更新我的答案
猜你喜欢
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
相关资源
最近更新 更多