tub*_*adc 2 python performance split pandas
我有一个数据集(大约10Gb)的通话记录.有ip地址的列我想分成四个新列.我正在尝试使用:
df['ip'].fillna('0.0.0.0', inplace=True)
df = df.join(df['ip'].apply(lambda x: Series(x.split('.'))))
Run Code Online (Sandbox Code Playgroud)
但是它太慢了...... fillna速度很快,就像10秒一样,但它会在5分钟内保持分裂...
有没有更好的方法呢?
cge*_*cge 11
事实证明,str.split熊猫(在core/strings.pyas中str_split)实际上非常缓慢; 它不再有效,并且仍然使用Python进行迭代,不提供任何加速.
实际上,见下文.熊猫在这方面的表现简直悲惨; 它不只是Python vs C迭代,因为使用Python列表做同样的事情是最快的方法!
有趣的是,有一个技巧解决方案要快得多:将系列编写成文本,然后再用'.'再次读取它.作为分隔符:
df[['ip0', 'ip1', 'ip2', 'ip3']] = \
pd.read_table(StringIO(df['ip'].to_csv(None,index=None)),sep='.')
Run Code Online (Sandbox Code Playgroud)
为了比较,我使用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
Run Code Online (Sandbox Code Playgroud)
好吧,所以我想比较所有这些只是使用Python列表和Python拆分,这应该比使用更高效的Pandas慢:
iplist = list(df['ip'])
%timeit [ x.split('.') for x in iplist ]
100 loops, best of 3: 10 ms per loop
Run Code Online (Sandbox Code Playgroud)
什么!?显然,对大量字符串进行简单字符串操作的最佳方法是完全抛弃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
Run Code Online (Sandbox Code Playgroud)
这里有一些非常错误的东西.
| 归档时间: |
|
| 查看次数: |
1651 次 |
| 最近记录: |