使用方括号访问 Pandas 列与使用点(类似属性)

2024-12-20 08:38:00
admin
原创
79
摘要:问题描述:在以下两种情况下:import pandas d = {'col1': 2, 'col2': 2.5} df = pandas.DataFrame(data=d, index=[0]) print(df['col2']) print(df.col2) 两种方法都可以用于对列进行索引并产生相同的结...

问题描述:

在以下两种情况下:

import pandas

d = {'col1': 2, 'col2': 2.5}
df = pandas.DataFrame(data=d, index=[0])

print(df['col2'])
print(df.col2)

两种方法都可以用于对列进行索引并产生相同的结果,那么它们之间有什么区别吗?


解决方案 1:

“点符号”,即df.col2为了方便而公开的属性访问。

您可以直接将 Series 上的索引、DataFrame 上的列以及 Panel 上的项目作为属性进行访问:

df['col2']作用相同:它返回pd.Series该列的。

关于属性访问的一些注意事项:

  • 您无法添加列(df.new_col = x不起作用,更糟糕的是:它实际上会默默地创建一个新属性而不是一个列 - 想想这里的 monkey-patching)

  • 如果列名中有空格或者列名是整数,则它将不起作用。

解决方案 2:

差异的简短答案:

  • []索引(方括号访问)具有对 DataFrame 列数据进行操作的全部功能。

  • 虽然属性访问(点访问)主要是为了方便访问现有的 DataFrame 列数据,但偶尔也有其局限性(例如特殊列名、创建新列)。


更多解释

Series 和 DataFrame 是 Pandas 中的核心类和数据结构,当然它们也是 Python 类,因此在涉及 Pandas DataFrame 和普通 Python 对象之间的属性访问时会有一些细微的区别。但它有很好的文档记录,很容易理解。只需注意以下几点:

  1. 在 Python 中,用户可以使用属性访问动态地将自己的数据属性添加到实例对象中。

>>> class Dog(object):
...     pass
>>> dog = Dog()
>>> vars(dog)
{}
>>> superdog = Dog()
>>> vars(superdog)
{}
>>> dog.legs = 'I can run.'
>>> superdog.wings = 'I can fly.'
>>> vars(dog)
{'legs': 'I can run.'}
>>> vars(superdog)
{'wings': 'I can fly.'}
  1. 在 pandas 中,索引与数据结构紧密相关,你可以将Series 上的索引、DataFrame 上的列作为属性访问

>>> import pandas as pd
>>> import numpy as np
>>> data = np.random.randint(low=0, high=10, size=(2,2))
>>> df = pd.DataFrame(data, columns=['a', 'b'])
>>> df
   a  b
0  7  6
1  5  8
>>> vars(df)
{'_is_copy': None, 
 '_data': BlockManager
    Items: Index(['a', 'b'], dtype='object')
    Axis 1: RangeIndex(start=0, stop=2, step=1)
    IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64,
 '_item_cache': {}}
  1. 但是,pandas 属性访问主要是为了方便读取和修改Series 或 DataFrame 的列的现有元素。

>>> df.a
0    7
1    5
Name: a, dtype: int64
>>> df.b = [1, 1]
>>> df
   a  b
0  7  1
1  5  1
  1. 而且,便利性是以牺牲完整功能为代价的。例如,您可以创建一个具有列名的 DataFrame 对象['space bar', '1', 'loc', 'min', 'index'],但不能将它们作为属性访问,因为它们不是有效的 Python 标识符(1, space bar)或与现有属性名称冲突。

>>> data = np.random.randint(0, 10, size=(2, 5))
>>> df_special_col_names = pd.DataFrame(data, columns=['space bar', '1', 'loc', 'min', 'index'])
>>> df_special_col_names
   space bar  1  loc  min  index
0          4  4    4    8      9
1          3  0    1    2      3
  1. 在这些情况下,、.loc.iloc索引[]是完全访问/操作 Series 和 DataFrame 对象的索引和列的定义方式。

>>> df_special_col_names['space bar']
0    4
1    3
Name: space bar, dtype: int64
>>> df_special_col_names.loc[:, 'min']
0    8
1    2
Name: min, dtype: int64
>>> df_special_col_names.iloc[:, 1]
0    4
1    0
Name: 1, dtype: int64
  1. 另一个重要的区别是尝试为 DataFrame 创建新列时。如您所见,df.c = df.a + df.b只需在核心数据结构旁边创建一个新属性,因此从版本0.21.0及更高版本开始,此行为将引发UserWarning(不再沉默)。

>>> df
   a  b
0  7  1
1  5  1
>>> df.c = df.a + df.b
__main__:1: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access`
>>> df['d'] = df.a + df.b
>>> df
   a  b  d
0  7  1  8
1  5  1  6
>>> df.c
0    8
1    6
dtype: int64
>>> vars(df)
{'_is_copy': None, 
 '_data': 
    BlockManager
    Items: Index(['a', 'b', 'd'], dtype='object')
    Axis 1: RangeIndex(start=0, stop=2, step=1)
    IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64
    IntBlock: slice(2, 3, 1), 1 x 2, dtype: int64, 
 '_item_cache': {},
 'c': 0    8
      1    6
      dtype: int64}
  1. 最后,要为 DataFrame 创建新列,切勿使用属性访问。正确的方法是使用[].loc索引

>>> df
   a  b
0  7  6
1  5  8
>>> df['c'] = df.a + df.b 
>>> # OR
>>> df.loc[:, 'c'] = df.a + df.b
>>> df # c is an new added column
   a  b   c
0  7  6  13
1  5  8  13

解决方案 3:

只要您使用简单名称访问单个列,它们就是一样的,但您可以使用括号表示法做更多的事情。只有df.col当列名是有效的 Python 标识符(例如,不包含空格和其他类似的东西)时,您才能使用。此外,如果您的列名与 pandas 方法名称(如sum)冲突,您可能会遇到意外情况。使用括号,您可以选择多个列(例如df[['col1', 'col2']])或添加一个新列(df['newcol'] = ...),而使用点访问则无法做到这一点。

您链接到的另一个问题也适用,但这是一个更普遍的问题。Python 对象可以定义.and[]运算符如何应用于它们。Pandas DataFrames 选择使它们在这种访问单个列的有限情况下相同,但有上述注意事项。

解决方案 4:

.符号在交互工作和探索时非常有用。但是,为了代码清晰并避免发生疯狂的事情,您绝对应该使用符号。以下是创建新列时应[]使用符号的示例。[]

df = pd.DataFrame(data={'A':[1, 2, 3],
                    'B':[4,5,6]})

# this has no effect
df.D = 11
df

    A  B
 0  1  4
 1  2  5
 2  3  6
# but this works
df['D'] = 11
df

Out[19]: 
   A  B   D
0  1  4  11
1  2  5  11  
2  3  6  11

解决方案 5:

如果您有这样的数据框(我推荐这些列名)...

df = pd.DataFrame({'min':[1,2], 'max': ['a','a'], 'class': [1975, 1981], 'sum': [3,4]})

print(df)

   min max  class  sum
0    1   a   1975    3
1    2   a   1981    4

一切看起来都很好,没有错误。您甚至可以通过df['min']等访问列...

print(df['min'])

0    1
1    2
Name: min, dtype: int64

但是,如果你尝试的话,df.<column_name>你会遇到问题:

print(df.min)

<bound method NDFrame._add_numeric_operations.<locals>.min of    min max  class  sum
0    1   a   1975    3
1    2   a   1981    4>

print(df.max)

<bound method NDFrame._add_numeric_operations.<locals>.max of    min max  class  sum
0    1   a   1975    3
1    2   a   1981    4>

print(df.class)

  File "<ipython-input-31-3472b02a328e>", line 1
    print(df.class)
             ^
SyntaxError: invalid syntax
    
print(df.sum)

<bound method NDFrame._add_numeric_operations.<locals>.sum of    min max  class  sum
0    1   a   1975    3
1    2   a   1981    4>
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   984  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   0  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   0  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   0  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用