遍历 pandas 中的行并计算唯一的主题标签
iterate over rows in pandas and count unique hashtags
我有一个包含数千条推文的 csv 文件。假设数据如下:
Tweet_id hashtags_in_the_tweet
Tweet_1 [trump, clinton]
Tweet_2 [trump, sanders]
Tweet_3 [politics, news]
Tweet_4 [news, trump]
Tweet_5 [flower, day]
Tweet_6 [trump, impeach]
如您所见,数据包含 tweet_id 和每条推文中的主题标签。我想要做的是转到所有行,最后给我一些值计数:
Hashtag count
trump 4
news 2
clinton 1
sanders 1
politics 1
flower 1
obama 1
impeach 1
考虑到 csv 文件包含 100 万行(100 万条推文),执行此操作的最佳方法是什么?
Counter
+ chain
Pandas 方法不是为列表系列设计的。不存在矢量化方法。一种方法是使用标准库中的 collections.Counter
:
from collections import Counter
from itertools import chain
c = Counter(chain.from_iterable(df['hashtags_in_the_tweet'].values.tolist()))
res = pd.DataFrame(c.most_common())\
.set_axis(['Hashtag', 'count'], axis=1, inplace=False)
print(res)
Hashtag count
0 trump 4
1 news 2
2 clinton 1
3 sanders 1
4 politics 1
5 flower 1
6 day 1
7 impeach 1
设置
df = pd.DataFrame({'Tweet_id': [f'Tweet_{i}' for i in range(1, 7)],
'hashtags_in_the_tweet': [['trump', 'clinton'], ['trump', 'sanders'], ['politics', 'news'],
['news', 'trump'], ['flower', 'day'], ['trump', 'impeach']]})
print(df)
Tweet_id hashtags_in_the_tweet
0 Tweet_1 [trump, clinton]
1 Tweet_2 [trump, sanders]
2 Tweet_3 [politics, news]
3 Tweet_4 [news, trump]
4 Tweet_5 [flower, day]
5 Tweet_6 [trump, impeach]
听起来您想要 collections.Counter
之类的东西,您可以这样使用...
from collections import Counter
from functools import reduce
import operator
import pandas as pd
fold = lambda f, acc, xs: reduce(f, xs, acc)
df = pd.DataFrame({'Tweet_id': ['Tweet_%s'%i for i in range(1, 7)],
'hashtags':[['t', 'c'], ['t', 's'],
['p','n'], ['n', 't'],
['f', 'd'], ['t', 'i', 'c']]})
fold(operator.add, Counter(), [Counter(x) for x in df.hashtags.values])
这给了你,
Counter({'c': 2, 'd': 1, 'f': 1, 'i': 1, 'n': 2, 'p': 1, 's': 1, 't': 4})
编辑:我认为 jpp 的回答会快很多。如果时间真的是一个限制,我会避免首先将数据读入 DataFrame
。我不知道原始的 csv
文件是什么样的,但是将它作为文本文件按行读取,忽略第一个标记,然后将其余的输入到 Counter
中可能会变得相当多快点。
np.hstack
and convert to pd.Series
then use value_counts
的替代方案。
import numpy as np
df = pd.Series(np.hstack(df['hashtags_in_the_tweet'])).value_counts().to_frame('count')
df = df.rename_axis('Hashtag').reset_index()
print (df)
Hashtag count
0 trump 4
1 news 2
2 sanders 1
3 impeach 1
4 clinton 1
5 flower 1
6 politics 1
7 day 1
使用np.unique
v,c=np.unique(np.concatenate(df.hashtags_in_the_tweet.values),return_counts=True)
#pd.DataFrame({'Hashtag':v,'Count':c})
即使问题看起来不同,但仍然是相关的 问题
unnesting(df,['hashtags_in_the_tweet'])['hashtags_in_the_tweet'].value_counts()
所以上面的所有答案都有帮助,但实际上没有用!我的数据存在的问题是:1) 某些推文 'hashtags'
的值是 nan
或 []
。 2)dataframe中'hashtags'
字段的值是一个字符串!上面的答案假定主题标签的值是主题标签列表,例如['trump', 'clinton']
,而它实际上只是一个 str
:'[trump, clinton]'
。所以我在@jpp 的回答中添加了一些行:
#deleting rows with nan or '[]' values for in column hashtags
df = df[df.hashtags != '[]']
df.dropna(subset=['hashtags'], inplace=True)
#changing each hashtag from str to list
df.hashtags = df.hashtags.str.strip('[')
df.hashtags = df.hashtags.str.strip(']')
df.hashtags = df.hashtags.str.split(', ')
from collections import Counter
from itertools import chain
c = Counter(chain.from_iterable(df['hashtags'].values.tolist()))
res = pd.DataFrame(c.most_common())\
.set_axis(['Hashtag', 'count'], axis=1, inplace=False)
print(res)
我有一个包含数千条推文的 csv 文件。假设数据如下:
Tweet_id hashtags_in_the_tweet
Tweet_1 [trump, clinton]
Tweet_2 [trump, sanders]
Tweet_3 [politics, news]
Tweet_4 [news, trump]
Tweet_5 [flower, day]
Tweet_6 [trump, impeach]
如您所见,数据包含 tweet_id 和每条推文中的主题标签。我想要做的是转到所有行,最后给我一些值计数:
Hashtag count
trump 4
news 2
clinton 1
sanders 1
politics 1
flower 1
obama 1
impeach 1
考虑到 csv 文件包含 100 万行(100 万条推文),执行此操作的最佳方法是什么?
Counter
+ chain
Pandas 方法不是为列表系列设计的。不存在矢量化方法。一种方法是使用标准库中的 collections.Counter
:
from collections import Counter
from itertools import chain
c = Counter(chain.from_iterable(df['hashtags_in_the_tweet'].values.tolist()))
res = pd.DataFrame(c.most_common())\
.set_axis(['Hashtag', 'count'], axis=1, inplace=False)
print(res)
Hashtag count
0 trump 4
1 news 2
2 clinton 1
3 sanders 1
4 politics 1
5 flower 1
6 day 1
7 impeach 1
设置
df = pd.DataFrame({'Tweet_id': [f'Tweet_{i}' for i in range(1, 7)],
'hashtags_in_the_tweet': [['trump', 'clinton'], ['trump', 'sanders'], ['politics', 'news'],
['news', 'trump'], ['flower', 'day'], ['trump', 'impeach']]})
print(df)
Tweet_id hashtags_in_the_tweet
0 Tweet_1 [trump, clinton]
1 Tweet_2 [trump, sanders]
2 Tweet_3 [politics, news]
3 Tweet_4 [news, trump]
4 Tweet_5 [flower, day]
5 Tweet_6 [trump, impeach]
听起来您想要 collections.Counter
之类的东西,您可以这样使用...
from collections import Counter
from functools import reduce
import operator
import pandas as pd
fold = lambda f, acc, xs: reduce(f, xs, acc)
df = pd.DataFrame({'Tweet_id': ['Tweet_%s'%i for i in range(1, 7)],
'hashtags':[['t', 'c'], ['t', 's'],
['p','n'], ['n', 't'],
['f', 'd'], ['t', 'i', 'c']]})
fold(operator.add, Counter(), [Counter(x) for x in df.hashtags.values])
这给了你,
Counter({'c': 2, 'd': 1, 'f': 1, 'i': 1, 'n': 2, 'p': 1, 's': 1, 't': 4})
编辑:我认为 jpp 的回答会快很多。如果时间真的是一个限制,我会避免首先将数据读入 DataFrame
。我不知道原始的 csv
文件是什么样的,但是将它作为文本文件按行读取,忽略第一个标记,然后将其余的输入到 Counter
中可能会变得相当多快点。
np.hstack
and convert to pd.Series
then use value_counts
的替代方案。
import numpy as np
df = pd.Series(np.hstack(df['hashtags_in_the_tweet'])).value_counts().to_frame('count')
df = df.rename_axis('Hashtag').reset_index()
print (df)
Hashtag count
0 trump 4
1 news 2
2 sanders 1
3 impeach 1
4 clinton 1
5 flower 1
6 politics 1
7 day 1
使用np.unique
v,c=np.unique(np.concatenate(df.hashtags_in_the_tweet.values),return_counts=True)
#pd.DataFrame({'Hashtag':v,'Count':c})
即使问题看起来不同,但仍然是相关的
unnesting(df,['hashtags_in_the_tweet'])['hashtags_in_the_tweet'].value_counts()
所以上面的所有答案都有帮助,但实际上没有用!我的数据存在的问题是:1) 某些推文 'hashtags'
的值是 nan
或 []
。 2)dataframe中'hashtags'
字段的值是一个字符串!上面的答案假定主题标签的值是主题标签列表,例如['trump', 'clinton']
,而它实际上只是一个 str
:'[trump, clinton]'
。所以我在@jpp 的回答中添加了一些行:
#deleting rows with nan or '[]' values for in column hashtags
df = df[df.hashtags != '[]']
df.dropna(subset=['hashtags'], inplace=True)
#changing each hashtag from str to list
df.hashtags = df.hashtags.str.strip('[')
df.hashtags = df.hashtags.str.strip(']')
df.hashtags = df.hashtags.str.split(', ')
from collections import Counter
from itertools import chain
c = Counter(chain.from_iterable(df['hashtags'].values.tolist()))
res = pd.DataFrame(c.most_common())\
.set_axis(['Hashtag', 'count'], axis=1, inplace=False)
print(res)