跟进a previous question,是否有一种首选的有效方式来获取列中每个对象的类型?这特别适用于列的dtype
为object
以允许列的元素之间存在异类型的情况(特别是,允许数字NaN
而不更改数据类型float
)的其他元素。
我还没有做过时间基准测试,但我对以下一些明显的想法(以及可能使用map
或filter
的变体)持怀疑态度。感兴趣的用例需要快速获取所有元素类型的信息,因此生成器等可能不会在这里产生效率。
# df is a pandas DataFrame with some column 'A', such that
# df['A'].dtype is 'object'
dfrm['A'].apply(type) #Or np.dtype, but this will fail for native types.
另一个想法是使用NumPy vectorize
函数,但这真的会更有效吗?例如,使用与上面相同的设置,我可以尝试:
import numpy as np
vtype = np.vectorize(lambda x: type(x)) # Gives error without lambda
vtype(dfrm['A'])
这两种想法都会产生可行的输出,但这是我担心的效率。
加
我继续在IPython中做了一个小小的基准测试。首先是上面的vtype
,然后是apply
路线。我重复了十几次,这个例子在我的机器上非常典型。
apply()
方法明显胜出,所以有充分的理由期望我不会比使用apply()
更有效吗?
适用于vtype()
In [49]: for ii in [100,1000,10000,100000,1000000,10000000]:
....: dfrm = pandas.DataFrame({'A':np.random.rand(ii)})
....: dfrm['A'] = dfrm['A'].astype(object)
....: dfrm['A'][0:-1:2] = None
....: st_time = time.time()
....: tmp = vtype(dfrm['A'])
....: ed_time = time.time()
....: print "%s:\t\t %s"%(ii, ed_time-st_time)
....:
100: 0.0351531505585
1000: 0.000324010848999
10000: 0.00209212303162
100000: 0.0224051475525
1000000: 0.211136102676
10000000: 2.2215731144
适用于apply()
In [50]: for ii in [100,1000,10000,100000,1000000,10000000]:
....: dfrm = pandas.DataFrame({'A':np.random.rand(ii)})
....: dfrm['A'] = dfrm['A'].astype(object)
....: dfrm['A'][0:-1:2] = None
....: st_time = time.time()
....: tmp = dfrm['A'].apply(type)
....: ed_time = time.time()
....: print "%s:\t %s"%(ii, ed_time-st_time)
....:
100: 0.000900983810425
1000: 0.000159025192261
10000: 0.00117015838623
100000: 0.0111050605774
1000000: 0.103563070297
10000000: 1.03093600273
答案 0 :(得分:3)
Series.apply
和Series.map
使用我编写的专门的Cython方法(pandas.lib.map_infer
),大约比使用numpy.vectorize
快2倍。