pandas .at 与 .loc

2025-03-13 08:51:00
admin
原创
53
摘要:问题描述:我一直在探索如何优化我的代码并遇到了pandas .at方法。根据文档快速基于标签的标量访问器与 loc 类似,at 提供基于标签的标量查找。您也可以使用这些索引器进行设置。因此我运行了一些样本:设置import pandas as pd import numpy as np from string...

问题描述:

我一直在探索如何优化我的代码并遇到了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 * 8180

问题

的局限性是什么.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方法可以做什么,不可以做什么?


解决方案 1:

更新: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[...] 调用df.get_value,但它也对键进行一些类型检查。

解决方案 2:

正如您询问的局限性.at,这是我最近遇到的一件事(使用 pandas 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: 十进制 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

解决方案 3:

除上述内容外,Pandas文档中还at指出:

访问行/列标签对的单个值。

与 loc 类似,两者都提供基于标签的查找。如果您只需要获取或设置 DataFrame 或 Series 中的单个值,请使用 at。

对于设置数据locat类似,例如:

df = pd.DataFrame({'A': [1,2,3], 'B': [11,22,33]}, index=[0,0,1])

locat产生相同的结果

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 中的一组行/列,而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可以用于匹配一组行/列,并且可以只给出一个索引,而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 column

解决方案 4:

.at是一种与 相比优化的数据访问方法.loc

.loc数据框选择由其参数中给出的 indexed_rows 和 labeled_columns 定位的所有元素。相反,.at选择位于给定 indexed_row 和 labeled_columns 的数据框的特定元素。

此外,.at以一行和一列作为输入参数,而.loc可能采用多行和多列。输出使用.at单个元素,.loc可能使用 Series 或 DataFrame。

解决方案 5:

的另一个限制.at.loc接受其他输入(以索引为交换),例如条件,而.at不能:

> df = pd.DataFrame([[1, 2], 
                   [0, 0],
                   ], 
                   columns=["A", "B"])

> df["A"] > 0 # is a pd.Series of bool values

> df.loc[df["A"] > 0, "B"] # provides the first line in this example

> df.at[df["A"] > 0, "B"] # using .at will raise InvalidIndexError
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2577  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   26  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   21  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   18  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用