1. ホーム
  2. パイソン

pandasのjoin操作の詳細

2022-02-25 01:13:08
<パス

プロジェクトのgithubアドレスです。 bitcarmanleeイージーアルゴリズムインタビューと実践
私はしばしば学生が私的な手紙やメッセージ、Vナンバーbitcarmanleeで関連する質問をすることがあります。github星の学生で、私の能力と時間で、スコープを可能にし、できるだけ一緒に、進行状況と、関連する質問に答えるのを助ける。

1. 前書き

結合操作はリレーショナルデータベースにおける中核的な操作の一つであるが、実際には最も問題が多く、しばしば最適化が必要とされる。データフレームをテーブルに例えるなら、当然、結合操作を伴いますし、非常に、一般的な操作です。それでは、pandasのjoinの使い方を詳しく見ていきましょう。

2. ジョインメソッドのプロトタイプ

pandasのソースコードにおけるjoinメソッドのシグネチャは以下の通りです。

    def join(
        self, other, on=None, how="left", lsuffix="", rsuffix="", sort=False
    ) -> "DataFrame":
        """
        Join columns of another DataFrame.

        Join columns with `other` DataFrame either on index or on a key
        Efficiently join multiple DataFrame objects by index at once by
        passing a list.

        Parameters
        ----------
        other : DataFrame, Series, or list of DataFrame
            Index should be similar to one of the columns in this one.
            Series is passed, its name attribute must be set, and that will be
            If a Series is passed, its name attribute must be set, and that will be used as the column name in the resulting joined DataFrame.
        on : str, list of str, or array-like, optional
            Column or index level name(s) in the caller to join on the index
            in `other`, otherwise joins index-on-index.
            values given, the `other` DataFrame must have a MultiIndex.
            pass an array as the join key if it is not already contained in
            Like an Excel VLOOKUP operation.
        how : {'left', 'right', 'outer', 'inner'}, default 'left'
            How to handle the operation of the two objects.

            * left: use calling frame's index (or column if on is specified)
            * right: use `other`'s index.
            * outer: form union of calling frame's index (or column if on is specified) with `other`'s index.
              outside: form union of calling frame's index (or column if on is specified) with `other`'s index, and sort it.
              lexicographically.
            * inner: form intersection of calling frame's index (or column if
              on is specified) with `other`'s index, preserving the order of the calling's one.
              lsuffix : str, default
        lsuffix : str, default ''
            Suffix to use from left frame's overlapping columns.
        rsuffix : str, default ''
            Suffix to use from right frame's overlapping columns.
        sort : bool, default False
            Order result DataFrame lexicographically by the join key. if False,
            If False, the order of the join key depends on the join type (how keyword).

        Returns
        -------
        DataFrame
            A dataframe containing columns from both the caller and `other`.



def join(self, other, on=None, how="left", lsuffix="", rsuffix="", sort=False)です。
ここで
他の DataFrame, Series, or list of DataFrame, another dataframe, series, or dataframe list.
on: sqlのonパラメータと同様に、結合に参加するカラムです。
どのように sqlのjoinメソッドと同様に、{'left', 'right', 'outer', 'inner '}, default 'left' となります。
lsuffix: 左側のDataFrameの重複する列の接尾辞
rsuffix: 右側のDataFrameで繰り返される列のサフィックス
sort: 連結されたキーの結果を辞書順に並べ替えます。

3. 指定した列で結合する

実際のところ、最も一般的な結合方法は、同一のカラムによる結合ですので、簡単な結合例を試してみましょう。

import pandas as pd

def joindemo():
    age_df = pd.DataFrame({'name': ['lili', 'lucy', 'tracy', 'mike'],
                           'age': [18, 28, 24, 36]})
    score_df = pd.DataFrame({'name': ['tony', 'mike', 'akuda', 'tracy'],
                             'score': ['A', 'B', 'C', 'B']})

    result = age_df.join(score_df, on='name')
    print(result)


上記のコードでは、以下のようなエラーが報告されます。

ValueError: You are trying to merge on object and int64 columns. If you wish to proceed you should use pd.concat


この理由は、データフレームのインデックスに基づいて結合が行われるからです。もし理解できない場合は、以下のテストコードで理解できます。

def joindemo2():
    age_df = pd.DataFrame({'name': ['lili', 'lucy', 'tracy', 'mike'],
                           'age': [18, 28, 24, 36]})
    score_df = pd.DataFrame({'name': ['tony', 'mike', 'akuda', 'tracy'],
                             'score': ['A', 'B', 'C', 'B']})
    print(age_df)
    age_df.set_index('name', inplace=True)
    print(age_df)


上記のコードは、以下のように実行されます。

    name age
0 lili 18
1 lucy 28
2 tracy 24
3 mike 36
       mike
lili      
lili 18
lucy 28
tracy 24
mike 36


データフレームのデフォルトのインデックスは0からの増加する整数で、先頭の0,1,2,3がインデックスです。インデックスをnameで指定すると、出力データフレームの構造が変化し、先頭の増加する数字が消えます。

冒頭の結合要件を実装するには、次のようなコードを実行します。

def joindemo():
    age_df = pd.DataFrame({'name': ['lili', 'lucy', 'tracy', 'mike'],
                           'age': [18, 28, 24, 36]})
    score_df = pd.DataFrame({'name': ['tony', 'mike', 'akuda', 'tracy'],
                             'score': ['A', 'B', 'C', 'B']})

    age_df.set_index('name', inplace=True)
    score_df.set_index('name', inplace=True)
    result = age_df.join(score_df, on='name')
    print(result)


このコードの出力は

       age score
name            
lili 18 NaN
lucy 28 NaN
tracy 24 B
mike 36 B


デフォルトは左結合で、上で必要なことを行います。

4. デフォルトの自己インクリメントインデックスで参加

デフォルトのセルフインクリメントインデックスで結合したい場合は、次にそれを試してみます。

def joindemo():
    age_df = pd.DataFrame({'name': ['lili', 'lucy', 'tracy', 'mike'],
                           'age': [18, 28, 24, 36]})
    score_df = pd.DataFrame({'name': ['tony', 'mike', 'akuda', 'tracy'],
                             'score': ['A', 'B', 'C', 'B']})

    result = age_df.join(score_df)
    print(result)


上記のコードもエラーを報告します

ValueError: columns overlap but no suffix specified: Index(['name'], dtype='object')


この時点で、lsuffix,rsuffixパラメータが必要です。

def joindemo():
    age_df = pd.DataFrame({'name': ['lili', 'lucy', 'tracy', 'mike'],
                           'age': [18, 28, 24, 36]})
    score_df = pd.DataFrame({'name': ['tony', 'mike', 'akuda', 'tracy'],
                             'score': ['A', 'B', 'C', 'B']})

    result = age_df.join(score_df, lsuffix='_left', rsuffix='_right')
    print(result)

  name_left age name_right score
0 lili 18 tony A
1 lucy 28 mike B
2 tracy 24 akuda C
3 mike 36 tracy B


  name_left age name_right score
0 lili 18 tony A
1 lucy 28 mike B
2 tracy 24 akuda C
3 mike 36 tracy B


5. マージとの違い

pandasには、joinを実装したmergeメソッドもあります。それらの具体的な違いについては、以下のリンクを参照してください。
https://stackoverflow.com/questions/22676081/what-is-the-difference-between-join-and-merge-in-pandas