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
我有一个过去 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