【问题标题】:Apply function to rows, unpack dictionary into multiple columns将函数应用于行,将字典解压成多列
【发布时间】:2018-04-05 20:00:24
【问题描述】:

我正在使用 NLTK 的 SentimentIntensityAnalyzer() 分析存储在 pandas 列中的语料库。使用 .polarity_scores() 返回一个包含四个键及其值的字典,即 neg、neu、pos 和 Compound。

我想遍历数据帧中的每一行,计算joined_corpus['body] 中包含的语料库的极性分数,然后将生成的字典解压成数据帧中的四列。我想不出办法将多个 key:value 对解压到 pandas 的一列中,所以我不得不使用以下 for 循环:

for index, row in joined_corpus.iterrows():
    sentiment = sid.polarity_scores(row['body'])
    joined_corpus.loc[index, 'neg'] = sentiment['neg']
    joined_corpus.loc[index, 'neu'] = sentiment['neu']
    joined_corpus.loc[index, 'pos'] = sentiment['pos']
    joined_corpus.loc[index, 'compound'] = sentiment['pos']
    print("sentiment calculated for "+ row['subreddit'] + "of" + str(sentiment))

这会产生如下输出:

sentiment calculated for 1200isplentyof{'neg': 0.067, 'neu': 0.745, 'pos': 0.188, 'compound': 1.0}
sentiment calculated for 2007scapeof{'neg': 0.092, 'neu': 0.77, 'pos': 0.138, 'compound': 0.9998}
sentiment calculated for 2b2tof{'neg': 0.123, 'neu': 0.768, 'pos': 0.109, 'compound': -0.9981}
sentiment calculated for 2healthbarsof{'neg': 0.096, 'neu': 0.762, 'pos': 0.142, 'compound': 0.9994}
sentiment calculated for 2meirl4meirlof{'neg': 0.12, 'neu': 0.709, 'pos': 0.171, 'compound': 0.9997}
sentiment calculated for 3DSof{'neg': 0.054, 'neu': 0.745, 'pos': 0.201, 'compound': 1.0}
sentiment calculated for 3Dprintingof{'neg': 0.056, 'neu': 0.812, 'pos': 0.131, 'compound': 1.0}
sentiment calculated for 3dshacksof{'neg': 0.055, 'neu': 0.804, 'pos': 0.141, 'compound': 1.0}
sentiment calculated for 40kLoreof{'neg': 0.123, 'neu': 0.747, 'pos': 0.13, 'compound': 0.9545}
sentiment calculated for 49ersof{'neg': 0.098, 'neu': 0.715, 'pos': 0.187, 'compound': 1.0}

然而,显然这很慢,因为它不使用 pandas 内置的 apply 命令。在这种情况下有没有办法避免 for 循环?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    通过使用应用

    sentiment = df['body'].apply(lambda x : sid.polarity_scores(x))
    df=pd.concat([df,sentiment.apply(pd.Series)],1)
    

    那么,

    "sentiment calculated for "+df['subreddit']+'of'+ sentiment.astype(str)
    

    【讨论】:

    • 鉴于我有一个庞大的数据集,是否有办法检查这个 apply 语句的进度?尝试使用 tqdm 库中的 progress_apply 不起作用,因为 apply 是在一个系列而不是一个数据帧上
    • @Parseltongue 如果你提到检查它,(意味着每个循环),我认为 for 循环是要走的路,正如你在原始帖子中列出的那样
    • @Parseltongue 我想是的,如果不是你可以看看numpy.vectorize docs.scipy.org/doc/numpy-1.10.0/reference/generated/…
    • 这看起来不像我需要的那样。这会将这样的字典: {'neg': 0.0, 'neu': 0.83, 'pos': 0.17, 'compound': 0.5719} 放入 pandas df 的列中。我想解压缩所有这些键并将它们作为单独的列添加到 df
    • @Parseltongue 将 pd.DataFrame(sentiment) 更改为 sentiment.apply(pd.Series)
    【解决方案2】:

    您可以为此使用列表推导:

    res = [sid.polarity_scores(x) for x in df['body']]
    
    for item in res:
        print(res)
    

    您也可以直接从此列表创建系列:

    df['sentiment'] = [sid.polarity_scores(x) for x in df['body']]
    

    【讨论】:

      猜你喜欢
      • 2019-07-29
      • 2019-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 2019-12-05
      • 2020-01-29
      • 2018-04-19
      相关资源
      最近更新 更多