对于Pandas DataFrame,使用方括号或点来访问列有什么区别?

时间:2016-12-13 20:45:50

标签: python pandas dataframe indexing

即:

import pandas

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

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

输出相同。

这个答案适用于这种情况吗?

What's the difference between the square bracket and dot notations in Python?

4 个答案:

答案 0 :(得分:31)

"点符号",即df.col2是为了方便而公开的attribute access

  

您可以直接将Panel上的索引,DataFrame上的列和Panel上的项目作为属性访问:

df['col2']执行相同的操作:它返回列的pd.Series

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

  • 你无法添加一列(df.new_col = x不会工作,更糟糕的是:它会默默地实际上创建一个新属性而不是列 - 想想猴子修补这里)< / LI>
  • 如果列名中有空格或列名是整数,它将无法工作。

答案 1 :(得分:13)

只要您使用简单名称访问单个列,它们就相同,但您可以使用括号表示法执行更多操作。如果列名是有效的Python标识符(例如,不包含空格和其他此类内容),则只能使用df.col。此外,如果您的列名与pandas方法名称(如sum)冲突,您可能会遇到意外。使用括号,您可以选择多个列(例如df[['col1', 'col2']])或添加新列(df['newcol'] = ...),这不能通过点访问来完成。

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

答案 2 :(得分:1)

简短回答差异

  • []索引(方括号访问)具有对DataFrame列数据进行操作的全部功能。
  • 属性访问(点访问)主要是为了方便地访问现有的DataFrame列数据,但偶尔也有其局限性(例如特殊的列名,创建新列)。

更多说明,Seires和DataFrame是熊猫的核心类和数据结构,当然它们也是Python类,因此在涉及熊猫DataFrame和普通Python对象之间的属性访问时,有一些细微的区别。但这是well documented,很容易理解。请注意以下几点:

  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.'}
    
  2. 在熊猫中,索引与数据结构密切相关,您可以访问系列索引, 作为属性在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': {}}
    
  3. 但是,熊猫属性访问主要是方便阅读和修改DataFrame系列或列的现有元素

    >>> df.a
    0    7
    1    5
    Name: a, dtype: int64
    >>> df.b = [1, 1]
    >>> df
       a  b
    0  7  1
    1  5  1
    
  4. 而且,便利性是对全部功能的折衷。例如。您可以使用列名['space bar', '1', 'loc', 'min', 'index']创建一个DataFrame对象,但是不能将它们作为属性访问,因为它们不是有效的Python标识符1space 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
    
  5. 在这些情况下,.loc.iloc[]的索引是the defined way,以完全访问/操作Series和DataFrame对象的索引和列。 / p>

    >>> 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
    
  6. 另一个重要的区别是在尝试为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}
    
  7. 最后,要为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 :(得分:-1)

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

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