web-dev-qa-db-ja.com

Pandas DataFrameの場合、角括弧またはドットを使用して列にアクセスすることの違いは何ですか?

すなわち:

import pandas

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

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

出力は同じです。

この回答はこのケースに適用されますか?

Pythonでの角括弧とドット表記の違いは何ですか?

40
Alberto Segundo

「ドット表記」、つまりdf.col2属性アクセス です。これは便宜上公開されています。

Seriesのインデックス、DataFrameの列、Panelの項目に属性として直接アクセスできます。

df['col2']は同じことを行います。列のpd.Seriesを返します。

属性アクセスに関するいくつかの警告:

  • 列を追加することはできません(df.new_col = xは機能しません。さらに悪いことに、静かに実際に列ではなく新しい属性を作成します-考えますモンキーパッチはこちら)
  • 列名にスペースが含まれている場合、または列名が整数の場合は機能しません。
37
Julien Marrec

単純な名前で単一の列にアクセスしている限りは同じですが、ブラケット表記を使用してさらに多くのことができます。 df.colを使用できるのは、列名が有効なPython識別子(たとえば、スペースやその他のものが含まれていない)の場合のみです。また、列名がpandasメソッド名(sumなど)と衝突します。角かっこを使用すると、複数の列(たとえば、df[['col1', 'col2']])を選択したり、新しい列(df['newcol'] = ...)、これはドットアクセスでは実行できません。

あなたがリンクした他の質問も当てはまりますが、それはもっと一般的な質問です。 Pythonオブジェクトは、.および[]演算子をどのように適用するかを定義します。Pandas DataFramesは同じものを選択しました単一の列にアクセスするこの限られたケースでは、上記の注意事項があります。

14
BrenBarn

違いの簡単な答え:

  • [] indexing(角括弧アクセス)には、DataFrame列データを操作するための完全な機能があります。
  • attribute access(dot access)は主に既存のDataFrame列データにアクセスするための利便性のためですが、時々制限があります(例:特別な列名、新規作成カラム)。

さらに説明すると、SeiresとDataFrameはパンダのコアクラスとデータ構造であり、もちろんPythonクラスでもあるため、pandas DataFrameとnormal 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.'}
    
  2. パンダでは、indexおよびcolumnはデータ構造に密接に関連しているため、アクセスできますシリーズのインデックス、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. ただし、pandas属性アクセスは、主に、シリーズまたは列の既存の要素の読み取りと変更の利便性です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、および[]のインデックス付けは 定義された方法 であり、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
    
  6. もう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}
    
  7. 最後に、DataFrameの新しい列を作成するには、属性accessを使用しないでください。正しい方法は、[]を使用することですまたは.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
    
2
YaOzI