我有一个包含字符串的熊猫列。我想获得整个专栏中所有单词的字数统计。如何在不循环每个值的情况下做到这一点的最佳方式是什么?大熊猫列中所有字数的总和
df = pd.DataFrame({'a': ['some words', 'lots more words', 'hi']})
当上df['a']
运行,你应该得到6
我有一个包含字符串的熊猫列。我想获得整个专栏中所有单词的字数统计。如何在不循环每个值的情况下做到这一点的最佳方式是什么?大熊猫列中所有字数的总和
df = pd.DataFrame({'a': ['some words', 'lots more words', 'hi']})
当上df['a']
运行,你应该得到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
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
您是否也可以为我的答案留出时间? Thx – piRSquared
@piRSquared我为你的约100微秒。迅速! – bunji
号码可以通过STR数坯料+ 1被得到,然后总和()
(df.a.str.count(' ')+1).sum()
使用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)]))
幼稚的测试结果
这绝对是他们中最快的。我可能会建议一个类似的变体,它的性能稍微超过'str.cat' - 'len(“”.join(df ['a'])。split())' –
@NickilMaveli请你检查一下我的新概念。如果错误,我会删除它 – piRSquared
您不需要。 LGTM –
在我这样做的过程中,v不错 – Charlie