我一直在探索如何优化我的代码,并运行了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().Tdf看起来像:
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在其中as print sdf.at[:, :]导致TypeError: unhashable type
所以很明显,即使意图是相似的,也不一样。
也就是说,谁能就.at方法可以做什么和不能做什么提供指导呢?
发布于 2016-05-13 18:04:00
更新:从0.21.0版本开始,df.get_value就不再受欢迎了。使用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[...] df.get_value,但是它也在键上做某些类型检查。
发布于 2018-06-08 12:24:42
当你问到.at的局限性时,我最近遇到了一件事(使用熊猫0.22)。让我们使用文献资料中的示例
df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]], index=[4, 5, 6], columns=['A', 'B', 'C'])
df2 = df.copy()
A B C
4 0 2 3
5 0 4 1
6 10 20 30如果我现在做了
df.at[4, 'B'] = 100结果看上去和预期的一样
A B C
4 0 100 3
5 0 4 1
6 10 20 30但是,当我试着做
df.at[4, 'C'] = 10.05.at 似乎试图保存数据类型(在这里: int**)**:)
A B C
4 0 100 10
5 0 4 1
6 10 20 30这似乎与.loc不同
df2.loc[4, 'C'] = 10.05产生所需的
A B C
4 0 2 10.05
5 0 4 1.00
6 10 20 30.00上面示例中的危险之处在于,它是无声发生的(从float到int的转换)。当您对字符串进行相同的尝试时,它会抛出一个错误:
df.at[5, 'A'] = 'a_string'ValueError:带基10的int()的无效文本:'a_string‘
但是,如果使用一个int()实际上在其上工作的字符串(如注释中的@n1k31t4所指出的那样),则它将工作。
df.at[5, 'A'] = '123'
A B C
4 0 2 3
5 123 4 1
6 10 20 30发布于 2020-06-08 20:09:01
除此之外,用于文档函数的Pandas at声明:
访问行/列标签对的单个值。 类似于loc,因为两者都提供基于标签的查找。如果您只需要在DataFrame或Series中获取或设置单个值,请使用at。
对于设置数据,loc和at类似,例如:
df = pd.DataFrame({'A': [1,2,3], 'B': [11,22,33]}, index=[0,0,1])loc和at都会产生相同的结果。
df.at[0, 'A'] = [101,102]
df.loc[0, 'A'] = [101,102]
A B
0 101 11
0 102 22
1 3 33
df.at[0, 'A'] = 103
df.loc[0, 'A'] = 103
A B
0 103 11
0 103 22
1 3 33另外,对于访问单个值,两者是相同的。
df.loc[1, 'A'] # returns a single value (<class 'numpy.int64'>)
df.at[1, 'A'] # returns a single value (<class 'numpy.int64'>)
3但是,当匹配多个值时,loc将从DataFrame返回一组行/cols,而at将返回一个值数组。
df.loc[0, 'A'] # returns a Series (<class 'pandas.core.series.Series'>)
0 103
0 103
Name: A, dtype: int64
df.at[0, 'A'] # returns array of values (<class 'numpy.ndarray'>)
array([103, 103])更重要的是,loc可以用于匹配一组行/cols,并且只能给出一个索引,而at必须接收该列。
df.loc[0] # returns a DataFrame view (<class 'pandas.core.frame.DataFrame'>)
A B
0 103 11
0 103 22
# df.at[0] # ERROR: must receive columnhttps://stackoverflow.com/questions/37216485
复制相似问题