2017-10-03 3 views
2

J'ai une base de données pandas qui contient des requêtes et des comptes pour une période de temps donnée et j'espère convertir cette base de données en un nombre de mots uniques. Par exemple, si la base de données contient le code suivant:Comptage des mots dans une colonne de chaînes dans les pandas

query   count 
foo bar  10 
super   8 
foo   4 
super foo bar 2 

Je souhaite recevoir l'image ci-dessous. par exemple. le mot «foo» apparaît exactement 16 fois dans le tableau.

word count 
foo  16 
bar  12 
super 10 

Je travaille avec la fonction ci-dessous, mais il ne semble guère être la meilleure façon de le faire et il ne tient pas compte du nombre total pour chaque ligne.

def _words(df): 
    return Counter(re.findall(r'\w+', ' '.join(df['query']))) 

Toute aide sera grandement appréciée.

Merci d'avance!

Répondre

5

Option 1

df['query'].str.get_dummies(sep=' ').T.dot(df['count']) 

bar  12 
foo  16 
super 10 
dtype: int64 

Option 2

df['query'].str.get_dummies(sep=' ').mul(df['count'], axis=0).sum() 

bar  12 
foo  16 
super 10 
dtype: int64 

Option 3
numpy.bincount + pd.factorize
soulignant également l'utilisation de cytoolz.mapcat. Il retourne un itérateur où il mappe une fonction et concatène les résultats. C'est super!

import pandas as pd, numpy as np, cytoolz 

q = df['query'].values 
c = df['count'].values 

f, u = pd.factorize(list(cytoolz.mapcat(str.split, q.tolist()))) 
l = np.core.defchararray.count(q.astype(str), ' ') + 1 

pd.Series(np.bincount(f, c.repeat(l)).astype(int), u) 

foo  16 
bar  12 
super 10 
dtype: int64 

Option 4
utilisation Absurde de choses ... il suffit d'utiliser l'option 1.

pd.DataFrame(dict(
    query=' '.join(df['query']).split(), 
    count=df['count'].repeat(df['query'].str.count(' ') + 1) 
)).groupby('query')['count'].sum() 

query 
bar  12 
foo  16 
super 10 
Name: count, dtype: int64 
+2

'Option 1 'est une pure beauté! – MaxU

+1

Prendre des notes :) – Vaishali

+1

Wow, merci pour toutes les réponses détaillées! L'option 1 fonctionne très bien. Merci beaucoup – Seano314

1

Juste une autre alternative avec melt + groupby + sum:

df['query'].str.split(expand=True).assign(count=df['count'])\ 
          .melt('count').groupby('value')['count'].sum() 

value 
bar  12 
foo  16 
super 10 
Name: count, dtype: int64