如何在熊猫列中计算逗号分隔的重复值?

时间:2018-05-09 11:55:10

标签: python string pandas dataframe

我有一个像这样的数据框列:

1    Applied Learning, Literacy & Language
2             Literacy & Language, Special Needs
3            Math & Science, Literacy & Language
4            Literacy & Language, Math & Science
6               Math & Science, Applied Learning
7                               Applied Learning
8                            Literacy & Language
10                                Math & Science...

每行都有逗号分隔值。我想要的是计算所有唯一值的出现。例如:Math&科学出现了4次。所以算数和数学科学应该是4.我尝试了以下代码:

cato=response['Category'].str.split(',')
cat_set=[]
for i in cato.dropna():
    cat_set.extend(i)
plt1=pd.Series(cat_set).value_counts().sort_values(ascending=False).to_frame()

但问题是,此代码适用于小型数据集,但大型数据集需要花费大量时间。对此有何解决方案?

由于

5 个答案:

答案 0 :(得分:3)

尝试使用专为高性能此类任务而构建的collections.Counter

假设您从

开始
df = pd.DataFrame({'Category': ['Applied Learning, Literacy & Language', 'Literacy & Language, Special Needs']})

然后做

import collections
import itertools
>>> collections.Counter(itertools.chain.from_iterable(v.split(',') for v in df.Category))

Counter({' Literacy & Language': 1,
         ' Special Needs': 1,
         'Applied Learning': 1,
         'Literacy & Language': 1})

答案 1 :(得分:2)

这是使用collections.Counteritertools.chain的一种方式。需要特别注意剥离空白。

为了提高性能,您应该对数据进行测试和基准测试。

from collections import Counter
from itertools import chain

s = pd.Series(['Applied Learning, Literacy & Language', 'Literacy & Language, Special Needs',
               'Math & Science, Literacy & Language', 'Literacy & Language, Math & Science',
               'Math & Science, Applied Learning', 'Applied Learning', 'Literacy & Language',
               'Math & Science'])

res = Counter(map(str.strip, chain.from_iterable(s.str.split(','))))

Counter({'Applied Learning': 3,
         'Literacy & Language': 5,
         'Math & Science': 4,
         'Special Needs': 1})

答案 2 :(得分:2)

使用scikit-learn -

的另一种方法
from sklearn.feature_extraction.text import CountVectorizer

vec = CountVectorizer(tokenizer=lambda x: [i.strip() for i in x.split(',')], lowercase=False)
counts = vec.fit_transform(df['text']) # actual count, output will be a sparse matrix
dict(zip(vec.get_feature_names(), counts.sum(axis=0).tolist()[0]))

此处CountVectorizer模块是自然语言处理中任何词汇建模的scikit-learn实现。

您可以将counts对象直接用作稀疏矩阵,有效地存储和计算,您还可以执行.sum(axis=0)之类的操作,这些操作按列求和。完成后,只需将其与vocabulary合并即可获得您想要的内容

<强>输出

{'Applied Learning': 3, 'Literacy & Language': 5, 'Math & Science': 4, 'Special
Needs': 1}

这适用于该列中的所有字词

答案 3 :(得分:0)

split = response['Category'].str.split(', ')

s = set()
for row in split:
    [s.add(el) for el in row]

for topic in s:    
    df[topic] = a.map(lambda x: topic in x)

这会导致df

                                       0  Literacy & Language  Math & Science  \
0  Applied Learning, Literacy & Language                 True           False   
1     Literacy & Language, Special Needs                 True           False   
2    Math & Science, Literacy & Language                 True            True   
3    Literacy & Language, Math & Science                 True            True   
4       Math & Science, Applied Learning                False            True   
5                       Applied Learning                False           False   
6                    Literacy & Language                 True           False   
7                         Math & Science                False            True   

   Applied Learning  Special Needs  
0              True          False  
1             False           True  
2             False          False  
3             False          False  
4              True          False  
5              True          False  
6             False          False  
7             False          False  

这样你就可以计算出真值的总和:

for topic in s:
    print(topic, df[topic].sum())

Literacy & Language 5
Math & Science 4
Applied Learning 3
Special Needs 1

答案 4 :(得分:0)

我想添加另一个可能的解决方案。我也在尝试解决该问题,并通过使用嵌套的理解获得了类似的信息:

example = pd.Series(['a', 'b, c', 'a, b', 'b', 'd', 'c'])

values = []

[[values.append(key) for key in record.split(', ')] for record in example.values.tolist()]

series = pd.Series(values)
series.value_counts().sort_index()