【发布时间】:2015-02-20 04:57:31
【问题描述】:
自己试试吧:
import pandas as pd
s=pd.Series(xrange(5000000))
%timeit s.loc[[0]] # You need pandas 0.15.1 or newer for it to be that slow
1 loops, best of 3: 445 ms per loop
更新:即a legitimate bug in pandas,可能在 2014 年 8 月左右在 0.15.1 中引入。解决方法:等待新版本同时使用旧版本的 pandas;获得尖端的开发人员。来自 github 的版本;在您的pandas 版本中手动进行一行修改;暂时用.ix代替.loc。
我有一个包含 480 万行的 DataFrame,使用 .iloc[[ id ]](带有单元素列表)选择单行需要 489 毫秒,几乎是半秒,比 1,800 倍慢相同的 .ix[[ id ]],并且比 .iloc[id] 慢 3,500 倍(将 id 作为值传递,而不是作为列表传递)。公平地说,.loc[list] 不管列表的长度如何,所花费的时间都差不多,但我不想在上面花费 489 毫秒,尤其是当 .ix 快一千倍时,并产生相同的结果。我的理解是.ix 应该更慢,不是吗?
我正在使用熊猫 0.15.1。 Indexing and Selecting Data 的优秀教程表明 .ix 在某种程度上比 .loc 和 .iloc 更通用,并且可能更慢。具体来说,它说
但是,当轴基于整数时,仅基于标签的访问和 不支持位置访问。因此,在这种情况下,通常 最好是明确的并使用 .iloc 或 .loc。
这是一个带有基准测试的 iPython 会话:
print 'The dataframe has %d entries, indexed by integers that are less than %d' % (len(df), max(df.index)+1)
print 'df.index begins with ', df.index[:20]
print 'The index is sorted:', df.index.tolist()==sorted(df.index.tolist())
# First extract one element directly. Expected result, no issues here.
id=5965356
print 'Extract one element with id %d' % id
%timeit df.loc[id]
%timeit df.ix[id]
print hash(str(df.loc[id])) == hash(str(df.ix[id])) # check we get the same result
# Now extract this one element as a list.
%timeit df.loc[[id]] # SO SLOW. 489 ms vs 270 microseconds for .ix, or 139 microseconds for .loc[id]
%timeit df.ix[[id]]
print hash(str(df.loc[[id]])) == hash(str(df.ix[[id]])) # this one should be True
# Let's double-check that in this case .ix is the same as .loc, not .iloc,
# as this would explain the difference.
try:
print hash(str(df.iloc[[id]])) == hash(str(df.ix[[id]]))
except:
print 'Indeed, %d is not even a valid iloc[] value, as there are only %d rows' % (id, len(df))
# Finally, for the sake of completeness, let's take a look at iloc
%timeit df.iloc[3456789] # this is still 100+ times faster than the next version
%timeit df.iloc[[3456789]]
输出:
The dataframe has 4826616 entries, indexed by integers that are less than 6177817
df.index begins with Int64Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], dtype='int64')
The index is sorted: True
Extract one element with id 5965356
10000 loops, best of 3: 139 µs per loop
10000 loops, best of 3: 141 µs per loop
True
1 loops, best of 3: 489 ms per loop
1000 loops, best of 3: 270 µs per loop
True
Indeed, 5965356 is not even a valid iloc[] value, as there are only 4826616 rows
10000 loops, best of 3: 98.9 µs per loop
100 loops, best of 3: 12 ms per loop
【问题讨论】:
-
请注意,使用
[[id]]和[id]是不等价的。[id]将返回一个系列,但[[id]]将返回一个单行数据帧。 -
@BrenBarn,是的,这解释了
.ix的区别:141 µs 与 270 µs。但是为什么.loc[[id]]这么慢?
标签: python performance pandas