【问题标题】:How can I get unique words from a DataFrame column of strings?如何从字符串的 DataFrame 列中获取唯一单词?
【发布时间】:2020-03-19 10:02:19
【问题描述】:

我正在寻找一种方法来获取 DataFrame 中的一列字符串中的唯一单词列表。

import pandas as pd
import numpy as np

df = pd.read_csv('FinalStemmedSentimentAnalysisDataset.csv', sep=';',dtype= 
       {'tweetId':int,'tweetText':str,'tweetDate':str,'sentimentLabel':int})

tweets = {}
tweets[0] = df[df['sentimentLabel'] == 0]
tweets[1] = df[df['sentimentLabel'] == 1]

我使用的数据集来自此链接:http://thinknook.com/twitter-sentiment-analysis-training-corpus-dataset-2012-09-22/

我得到了这个带有可变长度字符串的列,我想得到列中每个唯一单词的列表及其计数,我怎样才能得到它?我在 python 中使用 Pandas,原始数据库有超过 1M 的行,所以我还需要一些有效的方法来足够快地处理这个并且不会让代码运行太久。

列的示例可以是:

  • 为我的apl朋友感到难过。

  • 天哪,这太可怕了。

  • 这首新歌是什么?

    列表可能是这样的。

[is,so,sad,for,my,apl,friend,omg,this,terrible,what,new,song]

【问题讨论】:

标签: python pandas numpy dataframe bayesian-networks


【解决方案1】:

如果列中有字符串,则必须将每个句子拆分为单词列表,然后将所有列表放入一个列表中-您可以为此使用它sum()-它应该为您提供所有单词。要获得独特的单词,您可以将其转换为 set() - 稍后您可以转换回 list()

但在开始时,您必须清理句子以删除 .? 等字符。我使用 regex 仅保留一些字符和空格。最终,您必须将所有单词转换为小写或大写。

import pandas as pd

df = pd.DataFrame({
    'sentences': [
        'is so sad for my apl friend.',
        'omg this is terrible.',
        'what is this new song?',
    ]
})

unique = set(df['sentences'].str.replace('[^a-zA-Z ]', '').str.lower().str.split(' ').sum())

print(list(sorted(unique)))

结果

['apl', 'for', 'friend', 'is', 'my', 'new', 'omg', 'sad', 'so', 'song', 'terrible', 'this', 'what']

编辑:正如评论中提到的@HenryYik - findall('\w+') 可以用来代替split(),但也可以代替replace()

unique = set(df['sentences'].str.lower().str.findall("\w+").sum())

编辑:我用来自

的数据对其进行了测试

http://thinknook.com/twitter-sentiment-analysis-training-corpus-dataset-2012-09-22/

column.sum()sum(column) 外,所有操作都很快 - 我测量了 1000 行的时间并计算了 1 500 000 行,这需要 35 分钟。

使用itertools.chain() 要快得多 - 大约需要 8 秒。

import itertools

words = df['sentences'].str.lower().str.findall("\w+")
words = list(itertools.chain(words))
unique = set(words)

但可以直接转换为set()

words = df['sentences'].str.lower().str.findall("\w+")

unique = set()

for x in words:
    unique.update(x)

大约需要 5 秒


完整代码:

import pandas as pd
import time 

print(time.strftime('%H:%M:%S'), 'start')

print('-----')
#------------------------------------------------------------------------------

start = time.time()

# `read_csv()` can read directly from internet and compressed to zip
#url = 'http://thinknook.com/wp-content/uploads/2012/09/Sentiment-Analysis-Dataset.zip'
url = 'SentimentAnalysisDataset.csv'

# need to skip two rows which are incorrect
df = pd.read_csv(url, sep=',', dtype={'ItemID':int, 'Sentiment':int, 'SentimentSource':str, 'SentimentText':str}, skiprows=[8835, 535881])

end = time.time()
print(time.strftime('%H:%M:%S'), 'load:', end-start, 's')

print('-----')
#------------------------------------------------------------------------------

start = end

words = df['SentimentText'].str.lower().str.findall("\w+")
#df['words'] = words

end = time.time()
print(time.strftime('%H:%M:%S'), 'words:', end-start, 's')

print('-----')
#------------------------------------------------------------------------------

start = end

unique = set()
for x in words:
    unique.update(x)

end = time.time()
print(time.strftime('%H:%M:%S'), 'set:', end-start, 's')

print('-----')
#------------------------------------------------------------------------------

print(list(sorted(unique))[:10])

结果

00:27:04 start
-----
00:27:08 load: 4.10780930519104 s
-----
00:27:23 words: 14.803470849990845 s
-----
00:27:27 set: 4.338541269302368 s
-----
['0', '00', '000', '0000', '00000', '000000000000', '0000001', '000001', '000014', '00004873337e0033fea60']

【讨论】:

  • df["sentence"].str.findall("\w+") 跳过拆分部分。
  • @furas 我尝试了您的解决方案,但似乎无法正常工作,它停留在无限循环中,无法弄清楚为什么,我用一些关于我如何处理数据的额外信息编辑了这个问题,以及字符串已经被处理,没有任何标点符号并且全部小写。
  • 什么循环?我不使用任何循环,您没有显示任何有问题的循环 - 那么循环在哪里?也许更好地描述问题或显示更多代码。
  • 我为您的文件添加了运行速度更快的代码,该文件有 1 500 000 行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
相关资源
最近更新 更多