一尘不染

Pandas.at与.loc

python

我一直在探索如何优化代码并跨pandas .at方法运行。根据文档

基于标签的快速标量访问器

与loc相似,at提供基于标签的标量查找。您也可以使用这些索引器进行设置。

因此,我运行了一些示例:

设定

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方法可以做什么和不能做什么的指导?


阅读 202

收藏
2020-12-20

共1个答案

一尘不染

更新:df.get_value从0.21.0版开始不推荐使用。建议继续使用df.atdf.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[...]
调用df.get_value,但它还会对键进​​行一些类型检查

2020-12-20