2017-03-25 66 views
1

我有一个包含字符串的熊猫列。我想获得整个专栏中所有单词的字数统计。如何在不循环每个值的情况下做到这一点的最佳方式是什么?大熊猫列中所有字数的总和

df = pd.DataFrame({'a': ['some words', 'lots more words', 'hi']}) 

当上df['a']运行,你应该得到6

回答

6

您可以使用vectorized string operations

In [7]: df["a"].str.split().str.len().sum() 
Out[7]: 6 

它来自

In [8]: df["a"].str.split() 
Out[8]: 
0   [some, words] 
1 [lots, more, words] 
2     [hi] 
Name: a, dtype: object 

In [9]: df["a"].str.split().str.len() 
Out[9]: 
0 2 
1 3 
2 1 
Name: a, dtype: int64 

In [10]: df["a"].str.split().str.len().sum() 
Out[10]: 6 
+0

在我这样做的过程中,v不错 – Charlie

3
df.a.str.extractall('(\w+)').count()[0] 

这种提取物所有单词的每个单元格(正则表达式(\w+)匹配)在a,并把他们在一个新的框架,看起来像:

   0 
    match  
0 0  some 
    1  words 
1 0  lots 
    1  more 
    2  words 
2 0   hi 

那么你可以做一个count的行获得的单词数。

请注意,您可以随时更改正则表达式,如果你想。例如,如果有些话可能包含标点字符,你可以定义一个词作为任何系列的非空白字符,这样做:

df.a.str.extractall('(\S+)').count()[0] 

代替

编辑

如果你关心关于速度,请使用DSM的解决方案代替:

使用ipython的基本时间测试%timeit

话的个
%timeit df.a.str.extractall('(\S+)').count()[0] 
1000 loops, best of 3: 1.28 ms per loop 

%timeit df["a"].str.split().str.len().sum() 
1000 loops, best of 3: 447 µs per loop 
+0

您是否也可以为我的答案留出时间? Thx – piRSquared

+0

@piRSquared我为你的约100微秒。迅速! – bunji

1

号码可以通过STR数坯料+ 1被得到,然后总和()

(df.a.str.count(' ')+1).sum() 
5

使用cat字符串方法的另一种选择。我们将粉碎一切串在一起,然后分割和计数

len(df["a"].str.cat(sep=' ').split()) 

精心制作的测试数据

li = [ 
    'Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 
    'adipiscing', 'elit', 'Integer', 'et', 'tincidunt', 'nisl', 
    'Sed', 'pretium', 'arcu', 'nec', 'est', 'hendrerit', 
    'vestibulum', 'Curabitur', 'a', 'nibh', 'justo', 'Praesent', 
    'non', 'pellentesque', 'enim', 'ac', 'nulla', 'ut', 'mi', 
    'diam', 'Aenean', 'placerat', 'ante', 'euismod', 'pulvinar', 
    'augue', 'purus', 'ornare', 'erat', 'pharetra', 'mauris', 
    'sapien', 'vitae', 'In', 'id', 'velit', 'quis', 'mattis', 
    'condimentum', 'Cras', 'congue', 'neque', 'faucibus', 'nisi', 
    'tempor', 'eget', 'Etiam', 'semper', 'Nulla', 'elementum', 
    'magna', 'Donec', 'vel', 'ex', 'dictum', 'Aliquam', 'lobortis', 
    'rutrum', 'ligula', 'Vivamus', 'eu', 'eros', 'Morbi', 'blandit', 
    'rhoncus', 'consequat', 'orci', 'convallis', 'finibus', 'lorem', 
    'urna', 'molestie', 'in', 'sed', 'luctus', 'Ut', 'imperdiet', 
    'felis', 'Mauris', 'nunc', 'malesuada', 'lacinia', 'Vestibulum', 
    'bibendum', 'risus', 'tortor', 'sollicitudin', 'aliquam', 
    'primis', 'ultrices', 'posuere', 'cubilia', 'Curae', 
    'Phasellus', 'turpis', 'auctor', 'venenatis', 'Pellentesque', 
    'fermentum', 'accumsan', 'maximus', 'Fusce', 'ultricies', 
    'tristique', 'sodales', 'suscipit', 'sagittis', 'at', 'cursus', 
    'Nullam', 'dui', 'fringilla', 'mollis', 'Orci', 'varius', 
    'natoque', 'penatibus', 'magnis', 'dis', 'parturient', 'montes', 
    'nascetur', 'ridiculus', 'mus', 'facilisi', 'sem', 'viverra', 
    'feugiat', 'aliquet', 'lectus', 'porta', 'Nunc', 'facilisis', 
    'Duis', 'volutpat', 'scelerisque', 'Maecenas', 'tempus', 
    'massa', 'laoreet', 'gravida', 'odio', 'iaculis', 'libero', 
    'eleifend', 'leo', 'Quisque', 'ullamcorper', 'dignissim', 
    'interdum', 'vulputate', 'lacus', 'vehicula', 'Nam', 'commodo', 
    'dapibus', 'efficitur', 'tellus', 'Suspendisse', 'metus', 
    'Proin', 'quam', 'porttitor', 'egestas' 
] 

df = pd.DataFrame(
    dict(a=[' '.join(
      np.random.choice(li, np.random.randint(5, 10, 1)) 
    ) for _ in range(10000)])) 

幼稚的测试结果

enter image description here

+1

这绝对是他们中最快的。我可能会建议一个类似的变体,它的性能稍微超过'str.cat' - 'len(“”.join(df ['a'])。split())' –

+0

@NickilMaveli请你检查一下我的新概念。如果错误,我会删除它 – piRSquared

+0

您不需要。 LGTM –