Pandas 拆分一系列列表列表以查找单词 Count/Row

Pandas Split Series of List of Lists to Find Word Count/Row

我有一个过去 24 小时内按 dt.datetime 小时分组的推文数据框,其中每一行都是该小时内推文的 列表列表 我的目标 是为每一行拆分和展平这些推文,这样我就可以过滤掉停用词(the、a、but),并获得每小时推文的词频计数。我的实际数据每小时有 2-3k 条推文,因此由于最终目标是按以下格式对数据进行分组,因此我还需要按前 10-15 个最高计数过滤字数。

df=

      hour     tweets
0     1:00     ["['this darn tweet'], ['tweet']"]
1     2:00     ["['another tweet'], ['tweet'], ['tweet']"]
2     3:00     ["['this tweet'], ['this tweet']"]
3     4:00     ["['tweet'], ['this tweet']"]
4     5:00     ["['tweet'], ['another tweet'], ['yet another tweet'], ['tweet']"]

因为这个按小时分组的数据在数据框中而不是列表中,所以我能想到的唯一方法是某种形式的 Series.split() - 这会产生错误:

[in]:
df['tweets'] = [tweet.Series.split() for tweet in df['tweets']]
[out]:
AttributeError: 'list' object has no attribute 'split'

我对这个错误的研究已经深入,我似乎找不到任何在一系列列表列表上拆分的例子,但我怀疑这是某种形式的列表理解。

预期结果:

      hour     tweet  this     another   darn   yet
0     1:00     2      1        0         1      0
1     2:00     3      1        1         0      0
2     3:00     2      2        0         0      0
3     4:00     2      1        0         0      0
4     5:00     4      0        2         0      1

这不是完整的解决方案,而且很详细(这意味着它可以稍微清理一下,但是您迭代了一系列具有列表列表的行,所以我逐步执行此操作以查看什么很开心。

可能有正则表达式的方法先去掉所有的标点符号和括号,然后循环起来会更容易。因此,如果有人了解系列中的正则表达式,那将会很有帮助。

您可以计算列表中的字数,然后通过将列表发送到 set() 并制作新列表来找到唯一性。

tweets = ["['this darn tweet'], ['tweet']"]
print(type(tweets)
list_of_words = []
for tweet in tweets:
    print(tweet)
    print(type(tweet))
    print(tweet.replace('\'','').replace('[','').replace(']','').replace(',',''))
    tweet_stripped = tweet.replace('\'','').replace('[','').replace(']','').replace(',','')
    print(tweet_stripped.split())
    for word in tweet_stripped.split():
        print(word)
        list_of_words.append(word)
print(list_of_words)

这是输出字符串。你可以看到你是如何从一个列表开始的,所以你需要像列表一样处理它,然后每个你对一个字符串进行操作,收集单词

<class 'list'>
['this darn tweet'], ['tweet']
<class 'str'>
this darn tweet tweet
['this', 'darn', 'tweet', 'tweet']
this
darn
tweet
tweet
['this', 'darn', 'tweet', 'tweet']

要遍历系列,您需要将上面的所有内容包装在系列循环中 像

for r in df['tweets']:
    #insert above routine here

让我们试试:

stopwords = ['the', 'a', 'but']

# extract all the words from list of string
words = df['tweets'].str[0].str.extractall(r'(\w+)')[0]

# Remove stopwords and create frequency table
table = words[~words.isin(stopwords)].str.get_dummies().sum(level=0)

# join with hour column
df[['hour']].join(table)

详情:

首先使用.str.extractall:

提取tweets列中的所有单词
   match
0  0           this
   1           darn
   2          tweet
   3          tweet
1  0        another
   1          tweet
   2          tweet
   3          tweet
2  0           this
   1          tweet
   2           this
   3          tweet
3  0          tweet
   1           this
   2          tweet
4  0          tweet
   1        another
   2          tweet
   3            yet
   4        another
   5          tweet
   6          tweet
Name: 0, dtype: object

然后使用布尔掩码从上面提取的单词中删除 stopwords 并在 level=0 上使用 .str.get_dummies to encode the words into indicator/dummy variables. After encoding the words take .sum 来获取计数每个单词每个 hour:

   another  darn  this  tweet  yet
0        0     1     1      2    0
1        1     0     0      3    0
2        0     0     2      2    0
3        0     0     1      2    0
4        2     0     0      4    1

最后.join上面的频率table加上hour列得到想要的结果:

   hour  another  darn  this  tweet  yet
0  1:00        0     1     1      2    0
1  2:00        1     0     0      3    0
2  3:00        0     0     2      2    0
3  4:00        0     0     1      2    0
4  5:00        2     0     0      4    1