原来Pandas中的str.split(在core/strings.py中作为str_split)其实很慢;它不再高效,并且仍然使用 Python 进行迭代,没有提供任何加速。
其实,见下文。 Pandas 在这方面的表现简直惨不忍睹;这不仅仅是 Python 与 C 的迭代,因为使用 Python 列表做同样的事情是最快的方法!
不过,有趣的是,有一个更快的技巧解决方案:将 Series 写入文本,然后使用 '.' 再次读取它。作为分隔符:
df[['ip0', 'ip1', 'ip2', 'ip3']] = \
pd.read_table(StringIO(df['ip'].to_csv(None,index=None)),sep='.')
为了比较,我使用 Marius 的代码并生成 20,000 ips:
import pandas as pd
import random
import numpy as np
from StringIO import StringIO
def make_ip():
return '.'.join(str(random.randint(0, 255)) for n in range(4))
df = pd.DataFrame({'ip': [make_ip() for i in range(20000)]})
%timeit df[['ip0', 'ip1', 'ip2', 'ip3']] = df.ip.str.split('.', return_type='frame')
# 1 loops, best of 3: 3.06 s per loop
%timeit df[['ip0', 'ip1', 'ip2', 'ip3']] = df['ip'].apply(lambda x: pd.Series(x.split('.')))
# 1 loops, best of 3: 3.1 s per loop
%timeit df[['ip0', 'ip1', 'ip2', 'ip3']] = \
pd.read_table(StringIO(df['ip'].to_csv(None,index=None)),sep='.',header=None)
# 10 loops, best of 3: 46.4 ms per loop
好的,所以我想将所有这些与仅使用 Python 列表和 Python 拆分进行比较,这应该比使用更高效的 Pandas 慢:
iplist = list(df['ip'])
%timeit [ x.split('.') for x in iplist ]
100 loops, best of 3: 10 ms per loop
什么!?显然,对大量字符串进行简单字符串操作的最佳方法是完全抛弃 Pandas。 使用 Pandas 会使这个过程慢 400 倍。但是,如果你想使用 Pandas,你也可以只转换为 Python 列表并返回:
%timeit df[['ip0', 'ip1', 'ip2', 'ip3']] = \
pd.DataFrame([ x.split('.') for x in list(df['ip']) ])
# 100 loops, best of 3: 18.4 ms per loop
这里有一些非常错误。