我一直在探索如何优化我的代码并跑过 pandas
.at
方法。根据 documentation
Fast label-based scalar accessor
Similarly to loc, at provides label based scalar lookups. You can also set using these indexers.
所以我运行了一些样本:
设置
import pandas as pd
import numpy as np
from string import letters, lowercase, uppercase
lt = list(letters)
lc = list(lowercase)
uc = list(uppercase)
def gdf(rows, cols, seed=None):
"""rows and cols are what you'd pass
to pd.MultiIndex.from_product()"""
gmi = pd.MultiIndex.from_product
df = pd.DataFrame(index=gmi(rows), columns=gmi(cols))
np.random.seed(seed)
df.iloc[:, :] = np.random.rand(*df.shape)
return df
seed = [3, 1415]
df = gdf([lc, uc], [lc, uc], seed)
print df.head().T.head().T
df
看起来像:
a
A B C D E
a A 0.444939 0.407554 0.460148 0.465239 0.462691
B 0.032746 0.485650 0.503892 0.351520 0.061569
C 0.777350 0.047677 0.250667 0.602878 0.570528
D 0.927783 0.653868 0.381103 0.959544 0.033253
E 0.191985 0.304597 0.195106 0.370921 0.631576
让我们使用 .at
和 .loc
并确保我得到相同的东西
print "using .loc", df.loc[('a', 'A'), ('c', 'C')]
print "using .at ", df.at[('a', 'A'), ('c', 'C')]
using .loc 0.37374090276
using .at 0.37374090276
使用 .loc
%%timeit
df.loc[('a', 'A'), ('c', 'C')]
10000 loops, best of 3: 180 µs per loop
使用 .at
%%timeit
df.at[('a', 'A'), ('c', 'C')]
The slowest run took 6.11 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 8 µs per loop
这看起来是一个巨大的速度提升。即使在缓存阶段 6.11 * 8
也比 180
问题
.at
有什么限制?我有动力使用它。文档说它类似于 .loc
但它的行为并不相似。示例:
# small df
sdf = gdf([lc[:2]], [uc[:2]], seed)
print sdf.loc[:, :]
A B
a 0.444939 0.407554
b 0.460148 0.465239
其中 print sdf.at[:, :]
导致 TypeError: unhashable type
即使意图相似,显然也不相同。
也就是说,谁能提供关于 .at
方法可以做什么和不可以做什么的指导?
最佳答案
更新:df.get_value
自 0.21.0 版起已弃用。以后推荐使用 df.at
或 df.iat
方法。
df.at
一次只能访问一个值。
df.loc
可以选择多行和/或多列。
注意还有df.get_value
,这在访问单个值时可能会更快:
In [25]: %timeit df.loc[('a', 'A'), ('c', 'C')]
10000 loops, best of 3: 187 µs per loop
In [26]: %timeit df.at[('a', 'A'), ('c', 'C')]
100000 loops, best of 3: 8.33 µs per loop
In [35]: %timeit df.get_value(('a', 'A'), ('c', 'C'))
100000 loops, best of 3: 3.62 µs per loop
在后台,df.at[...]
calls df.get_value
, 但它也有 some type checking键上。
关于python - Pandas .at 与 .loc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37216485/