【问题标题】:how to do nested loop using apply in pandas如何在熊猫中使用apply进行嵌套循环
【发布时间】:2021-11-10 02:05:22
【问题描述】:

我有一个这样的数据框:

text,                pos
No thank you.        [(No, DT), (thank, NN), (you, PRP)]
They didn't respond  [(They, PRP), (didn't, VBP), (respond, JJ)]

我想在pos 上应用一个函数并将结果保存在一个新列中。所以输出看起来像这样:

text,                pos                                           score
No thank you.        [(No, DT), (thank, NN), (you, PRP)]        [[0.0, 0.0, 1.0], [], [0.5, 0.0, 0.45]]
They didn't respond  [(They, PRP), (didn, VBP), (respond, JJ)]  [[0.0, 0.0, 1.0], [], [0.75, 0.0, 0.25]]

所以函数为列表中的每个元组返回一个列表(但函数的实现不是这里的重点,为此我只是调用get_sentiment )。 我可以使用嵌套循环来做到这一点,但我不喜欢它。我想使用更 Pythonic 和 Pandas Dataframe 的方式来做到这一点:

这是我迄今为止尝试过的:

df['score'] = df['pos'].apply(lambda k: [get_sentiment(x,y) for j in k for (x,y) in j])

但是,它会引发此错误:

ValueError: too many values to unpack (expected 2)

so中有几个问题,但答案在R中。

为了更清楚:

get_sentiment 函数是NLTK 中的一个函数,它为每个单词分配一个分数列表(该列表是[positive score, negative score, objectivity score])。总的来说,我需要在我的 Dataframe 的 pos 列之上应用该函数。

【问题讨论】:

  • 这些列表中的值的参考或参考是什么?例如,您如何确定(No, DT) 转换为[0.0, 0.0, 1.0]
  • @ashkangh 我已经调用了NLTKget_sentiment 函数。所以它的作用是为每个单词分配一个分数。但我不需要该部分,因为该功能已经完美运行。我不知道如何在我的 Dataframe 中的 pos 列之上应用该函数。
  • @ashkangh 该列表是[positive score, negative score, objectivity score]。这是分配给每个元组的列表。但我觉得我们不需要这个细节,因为我的问题更笼统,是如何合并两个嵌套循环并应用。
  • 假设 get_sentiment 函数完全按照您的说法 - 将元组作为唯一参数并返回分数列表,也许这样的事情会起作用? df['score'] = df['pos'].apply(lambda k: [get_sentiment(j) for j in k])

标签: python pandas nested-loops


【解决方案1】:

让我们将 Pandas 排除在等式之外并创建一个问题的minimal reproducible example - 这与 lambda 本身有关:

def mock_sentiment(word, pos):
    return len(word) * 0.1, 0, len(pos) * 0.1

data = [('No', 'DT'), ('thank', 'NN'), ('you', 'PRP')]

[mock_sentiment(x, y) for j in data for (x,y) in j] # reproduces the error

问题在于每个j in data(例如('No', 'DT'))都是一个单个元组,我们希望将其解压缩为x, y值。通过迭代in j,我们得到单独的字符串('No''DT'),然后我们尝试将它们解包到xy。这恰好适用于 'No''DT',但不适用于其他长度的字符串 - 即便如此,这也不是预期的结果。

由于j 已经是我们要解包的元组,我们要做的是在那里解包它,使用(x, y) 而不是 @987654335 @ 用于迭代,并且没有任何嵌套理解:

[mock_sentiment(x, y) for (x, y) in data] # works as expected

因此,that 是我们希望 lambda 在真实代码中回馈给 Pandas 的内容(代入您的姓名和真实情感函数):

df['score'] = df['pos'].apply(lambda k: [get_sentiment(x, y) for (x, y) in k])

【讨论】:

    【解决方案2】:

    你的情况

    df['score'] = df['pos'].apply(lambda k: [get_sentiment(j[0],j[1]) for j in k ])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 2021-07-03
      • 2015-11-01
      • 2019-10-31
      • 2021-11-27
      • 1970-01-01
      相关资源
      最近更新 更多