Pandas基礎

23 min

正直、pandas DataFrameを使いたくないです。いつも使いにくいと感じます。まだスキルレベルが足りないのかもしれません。しかし、研究室のExcelファイルの読み書きやExcelへの出力で使わざるを得ないことが多いです。以前使っていたseabornもpandasベースなので、基本操作を復習しましょう。

読み書きと作成

データの読み書き

SQL

  • 読み込み
import pandas as pd
from sqlalchemy import create_engine
db = create_engine("mysql+pymysql://username:password@localhost:port(3306)/database_name?charset=utf8")
sql = "select * from text"
df = pd.read_sql(sql, db, index_col="index") # index_colでインデックス列を設定、デフォルトは自動生成
  • 書き込み
sql.to_sql(df, name='test', con=db,
                 if_exists="append", # テーブルが存在する場合: append, replace(削除して再作成), fail(挿入しない)
                 index=False # dfのインデックスをデータベースに挿入しない
                 )

Excel

  • 読み込み
df = pd.read_excel(r'file_path',
                   sheet_name='シートを指定、デフォルトは最初',
                   index=False, # Excelからインデックスを読み込まない、新しいインデックスを自動生成
                   index_col=0, # 列0をインデックスに設定
                   header=0, # 行nを列名に設定、デフォルトは0、Noneも可(0-n列を自動生成)
                   usecols=[0, 2] # 列0、2のみインポート
                   )
  • 書き込み
'''
異なるシートに書き込み
'''
# ワークブックを作成
excelWriter = pd.ExcelFile('file_path/test.xlsx')
# ワークブックに書き込み
df.to_excel(
    excelWriter,
    sheet_name='',
    index=False, # dfのインデックスをExcelに書き込まない
    encoding='utf-8',
    columns=['a', 'b'], # 書き込む列を指定
    na_rep=0, # 欠損値処理(0で埋める)
    inf_rep=0, # 無限大処理(0で埋める)
)
# 保存(保存しないと反映されない)
excelWriter.save()
'''
直接書き込み
'''
df.to_excel('file_path/test.xlsx') # パラメータ: index, encoding, columns, na_rep, inf_rep

CSV

  • 読み込み
df = pd.read(
    r'file_path/test.csv',
    sep="", # 区切り文字を指定、デフォルトはカンマ
    nrows=2, # 読み込む行数を指定
    encoding='utf-8',
    engine='python', # パスに日本語が含まれる場合に追加
    usecols=[0, 2], # 列0、2のみインポート
    index_col=0, # 列0をインデックスに設定
    header=0 # 行nを列名に設定、デフォルトは0、Noneも可
)
  • 書き込み
df.to_csv(
    r'file_path/test.csv',
    index=False, # インデックス列を書き込まない
    columns=['a', 'b'], # 書き込む列を指定
    sep=',', # 区切り文字を設定(デフォルトはカンマ)
    na_rep=0, # 欠損値を0で埋める
    encoding='utf-8',
)

TXT

  • 読み込み
pd.read_table(r'file_path/test.txt', sep='') # CSVファイルも読み込み可能

作成

一番困るのは、DataFrameにはnp.zeros、np.onesのような既存のDataFrameに基づいて空のDataFrameを初期化する関数がないことです。

df_empty=pd.Dataframe(columns=['A','B','C','D'])

そのため、既存のDataFrameから列名を抽出して新しいものを作成する方法があります。

インデックス

Pandasのデータインデックスは本の目次のようなもので、欲しい章をすばやく見つけることができます。大量のデータに対して、合理的でビジネス上意味のあるインデックスを作成することは、データ分析にとって非常に重要です。

インデックスの理解

以下は簡単なDataFrameのインデックスの例です:

pandas index
pandas index

ここで:

  • 行インデックスはデータのインデックス、列インデックスはSeriesを指す
  • DataFrameのインデックスはSeriesを形成するSeriesのインデックスでもある
  • インデックスを構築するとデータがより直感的になる(例:各行は特定の国のデータ)
  • インデックスを構築するとデータ処理が容易になる
  • インデックスは重複を許可するが、ビジネス上は通常重複させない

行と列のレベルが多いデータではマルチレベルインデックスが発生することがあります。

インデックスの構築

以前、データを読み込んでDataFrameを生成する際にインデックスを指定できることを学びました:

data = 'https://www.gairuo.com/file/data/dataset/team.xlsx'
df = pd.read_excel(data, index_col='name') # インデックスをnameに設定
df
'''
      team  Q1  Q2  Q3  Q4
name
Liver    E  89  21  24  64
Arry     C  36  37  37  57
Ack      A  57  60  18  84
Eorge    C  93  96  71  78
Oah      D  65  49  61  86
'''

読み込み時にインデックスを指定しなかった場合、df.set_index()を使用して指定できます:

df.set_index('month') # monthをインデックスに設定
df.set_index(['month', 'year']) # monthとyearをマルチレベルインデックスに設定
'''
            sale
month year
1     2012    55
4     2014    40
      2013    84
10    2014    31
'''

s = pd.Series([1, 2, 3, 4])
df.set_index(s) # インデックスを指定
df.set_index([s, 'year']) # カスタムインデックスと既存フィールドの両方を指定
df.set_index([s, s**2]) # 計算されたインデックス

# その他のパラメータ
df.set_index('month', drop=False) # 元の列を保持
df.set_index('month', append=True) # 元のインデックスを保持
df.set_index('month', inplace=True) # インデックスを構築してdfを上書き

インデックスのリセット

既存のインデックスをキャンセルしてやり直したい場合は、df.reset_index()を使用できます:

df.reset_index() # インデックスをクリア
df.set_index('month').reset_index() # 何もしないのと同じ
# 元のインデックスを削除、month列がなくなる
df.set_index('month').reset_index(drop=True)
df2.reset_index(inplace=True) # 上書きして有効にする
# yearレベルのインデックスをキャンセル
df.set_index(['month', 'year']).reset_index(level=1)
df2.reset_index(level='class') # 上記と同じ、レベルインデックス名を使用
df.reset_index(level='class', col_level=1) # 列インデックス
# 存在しないレベル名に指定した名前を入力
df.reset_index(level='class', col_level=1, col_fill='species')

インデックスの種類

様々なビジネスデータ処理に対応するため、インデックスには様々なデータ型に対応した異なる種類が定義されています:

数値インデックス Numeric Index

以下の種類があります:

  • RangeIndex: 単調整数範囲の不変インデックス
  • Int64Index: int64型、順序付きスライス可能な集合の不変ndarray
  • UInt64Index: 符号なし整数ラベル用
  • Float64Index: Float64型
pd.RangeIndex(1,100,2)
# RangeIndex(start=1, stop=100, step=2)
pd.Int64Index([1,2,3,-4], name='num')
# Int64Index([1, 2, 3, -4], dtype='int64', name='num')
pd.UInt64Index([1,2,3,4])
# UInt64Index([1, 2, 3, 4], dtype='uint64')
pd.Float64Index([1.2,2.3,3,4])
# Float64Index([1.2, 2.3, 3.0, 4.0], dtype='float64')

カテゴリインデックス CategoricalIndex

カテゴリは限られた数の(通常は固定の)可能な値(カテゴリ)のみを含むことができます。列挙型のようなもので、性別は男女のみですが、データの各行に出現します。テキストとして処理すると効率が悪くなります。基盤はpandas.Categoricalです。

pd.CategoricalIndex(['a', 'b', 'a', 'b'])
# CategoricalIndex(['a', 'b', 'a', 'b'], categories=['a', 'b'], ordered=False, dtype='category')

カテゴリについては後で詳しく説明します。非常に大きなデータセットでのみその利点が発揮されます。

間隔インデックス IntervalIndex

pd.interval_range(start=0, end=5)
'''
IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]],
              closed='right',
              dtype='interval[int64]')
'''

マルチインデックス MultiIndex

チュートリアルの後半で詳しく説明します。

arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))
'''
MultiIndex([(1,  'red'),
            (1, 'blue'),
            (2,  'red'),
            (2, 'blue')],
           names=['number', 'color'])
'''

日時インデックス DatetimeIndex

# ある日付から別の日付まで連続
pd.date_range(start='1/1/2018', end='1/08/2018')
# 開始時間と期間を指定
pd.date_range(start='1/1/2018', periods=8)
# 月単位の期間
pd.period_range(start='2017-01-01', end='2018-01-01', freq='M')
# ネストされた期間
pd.period_range(start=pd.Period('2017Q1', freq='Q'),
                end=pd.Period('2017Q2', freq='Q'), freq='M')

時間差 TimedeltaIndex

pd.TimedeltaIndex(data =['06:05:01.000030', '+23:59:59.999999',
                         '22 day 2 min 3us 10ns', '+23:29:59.999999',
                         '+12:19:59.999999'])
# datetimeを使用
pd.TimedeltaIndex(['1 days', '1 days, 00:00:05',
                   np.timedelta64(2, 'D'),
                   datetime.timedelta(days=2, seconds=2)])

期間インデックス PeriodIndex

t = pd.period_range('2020-5-1 10:00:05', periods=8, freq='S')
pd.PeriodIndex(t,freq='S')

インデックスオブジェクト

Pandasの行と列のインデックスは実際にはIndexオブジェクトです。indexオブジェクトを作成する方法は以下の通りです:

オブジェクトの作成

pd.Index([1, 2, 3])
# Int64Index([1, 2, 3], dtype='int64')
pd.Index(list('abc'))
# Index(['a', 'b', 'c'], dtype='object')
# 名前を定義できる
pd.Index(['e', 'd', 'a', 'b'], name='something')

表示

df.index
# RangeIndex(start=0, stop=4, step=1)
df.columns
# Index(['month', 'year', 'sale'], dtype='object')

プロパティ

以下のメソッドはdf.columnsにも適用されます(すべてインデックスオブジェクトなので):

# プロパティ
df.index.name # 名前
df.index.array # 配列
df.index.dtype # データ型
df.index.shape # 形状
df.index.size # 要素数
df.index.values # 配列
# その他、あまり使わない
df.index.empty # 空かどうか
df.index.is_unique # 重複がないか
df.index.names # 名前のリスト
df.index.is_all_dates # すべて日時か
df.index.has_duplicates # 重複があるか
df.index.values # インデックス値の配列

操作

以下のメソッドはdf.columnsにも適用されます(すべてインデックスオブジェクトなので):

# メソッド
df.index.astype('int64') # 型変換
df.index.isin() # 存在確認、下記の例を参照
df.index.rename('number') # インデックス名を変更
df.index.nunique() # ユニーク値の数
df.index.sort_values(ascending=False,) # ソート、降順
df.index.map(lambda x:x+'_') # map関数で処理
df.index.str.replace('_', '') # 文字列置換
df.index.str.split('_') # 分割
df.index.to_list() # リストに変換
df.index.to_frame(index=False, name='a') # DataFrameに変換
df.index.to_series() # Seriesに変換
df.index.to_numpy() # numpyに変換
df.index.unique() # 重複削除
df.index.value_counts() # 重複削除とカウント
df.index.where(df.index=='a') # フィルタ
df.index.rename('grade', inplace=False) # インデックス名を変更
df.index.rename(['species', 'year']) # マルチレベル、インデックス名を変更
df.index.max() # 最大値
df.index.argmax() # 最大値のインデックス
df.index.any()
df.index.all()
df.index.T # 転置、マルチレベルインデックスで便利

インデックスの名前変更

行と列のインデックス名を変更します。

# 列インデックスを一対一で変更
df.rename(columns={"A": "a", "B": "c"})
df.rename(str.lower, axis='columns')
# 行インデックスを変更
df.rename(index={0: "x", 1: "y", 2: "z"})
df.rename({1: 2, 2: 4}, axis='index')
# データ型を変更
df.rename(index=str)
# インデックスを再変更
replacements = {l1:l2 for l1, l2 in zip(list1, list2)}
df.rename(replacements)

インデックス名の名前変更

注意:これはインデックスの名前を変更するもので、インデックスや列名自体ではありません:

s.rename_axis("animal") # インデックス名を変更
df.rename_axis(["dow", "hr"]) # マルチレベルインデックス名を変更
df.rename_axis('info', axis="columns") # 行インデックス名を変更
# マルチレベル列インデックス名を変更
df.rename_axis(index={'a': 'A', 'b': 'B'})
# マルチレベル列行インデックス名を変更
df.rename_axis(columns={'name': 's_name', 'b': 'B'})
df.rename_axis(columns=str.upper) # 行インデックス名を大文字に

クエリと変更

データ検査

データを取得したら、まずスポットチェックが必要です。一方ではデータ構造を理解し、他方ではデータ品質の問題をランダムにチェックします。よく使うメソッド:

構文操作戻り値の型
df.head(n)DataFrameの最初のn行を表示DataFrame
df.tail(n)DataFrameの最後のn行を表示DataFrame
df.sample(n)n個のランダムサンプルを表示DataFrame

上記はすべて行全体を選択します。

先頭を表示 df.head()

データを読み込んだ後、通常は先頭データを確認する必要があります:

df.head()
out:
    name team  Q1  Q2  Q3  Q4
0  Liver    E  89  21  24  64
1   Arry    C  36  37  37  57
2    Ack    A  57  60  18  84
3  Eorge    C  93  96  71  78
4    Oah    D  65  49  61  86

# 数量を指定可能
df.head(15)

末尾を表示 df.tail()

最後の末尾データを表示します。

df.tail()
out:
        name team  Q1  Q2  Q3  Q4
95   Gabriel    C  48  59  87  74
96   Austin7    C  21  31  30  43
97  Lincoln4    C  98  93   1  20
98       Eli    E  11  74  58  91
99       Ben    E  21  43  41  74

# 数量を指定可能
df.tail(15)

サンプルを表示 df.sample()

df.sample()はランダムに1つのサンプルデータを返します。

df.sample()
out:
     name team  Q1  Q2  Q3  Q4
79  Tyler    A  75  16  44  63

# 数量を指定可能
df.sample(15)

データの切り取り:

# インデックスの前後のデータを削除
df.truncate(before=2, after=4) # インデックス2-4のみ保持
s.truncate(before="60", after="66")
df.truncate(before="A", after="B", axis="columns") # 列を選択

列操作

以下の両方の方法で列を表すことができます:

df['name'] # 列のSeriesを返す
df.name
df.Q1
# df.1Q 列名が1Qでも使用不可
# df.my name スペースがあると呼び出せない、アンダースコアを追加して処理可能

列名が有効なPython変数の場合、属性として直接使用できます。

行と列の選択

条件に基づいて一部の列や行を選択する必要がある場合があります。よく使うメソッド:

操作構文戻り値の型
列を選択df[col]Series
インデックスで行選択df.loc[label]Series
位置で行選択df.iloc[loc]Series
スライスで行選択df[5:10]DataFrame
式で行フィルタdf[bool_vec]DataFrame

スライス []

リストのようにスライス機能を使用して一部の行データを選択できますが、単一インデックスはサポートされていません:

df[:2] # 最初の2行
df[4:10]
df[:] # すべてのデータ、通常は使わない
df[:10:2] # ステップで取得
s[::-1] # 順序を反転

列も選択できます:

df['name'] # 1列のみ、Series
df[['Q1', 'Q2']] # 2列を選択
df[['name']] # 1列を選択、DataFrameを返す、上記との違いに注意

ラベルで .loc

df.loc()の形式はdf.loc[<インデックス式>, <列式>]で、式は以下の形式をサポートします:

単一ラベル:

# インデックスを表す、文字列は引用符が必要
df.loc[0] # インデックス0の行を選択
df.loc[8]

単一ラベルのリスト:

df.loc[[0,5,10]] # インデックス0、5、10の行
df.loc[['Eli', 'Ben']] # インデックスがnameの場合
# ブール選択、長さはインデックスと一致する必要がある
df.loc[[False, True]*50] # Trueの行を表示、1つおき

ラベル付きスライス(開始と終了を含む):

df.loc[0:5] # インデックススライス、行0-5、5を含む
df.loc['2010':'2014'] # インデックスが時間の場合、文字列でクエリ可能
df.loc[:] # すべて
# このメソッドはSeriesをサポート

列フィルタリング、行フィルタリングが必要:

dft.loc[:, ['Q1', 'Q2']] # すべての行、Q1とQ2列
dft.loc[:10, 'Q1':] # 行0-10、Q1以降のすべての列

位置で .iloc

df.ilocdf.locに似ていますが、自然インデックス(行と列の0-nインデックス)のみ使用でき、ラベルは使用できません。

df.iloc[:3]
df.iloc[:]
df.iloc[2:20:3]
s.iloc[:3]

特定の値を取得 .at

locに似ていますが、単一の特定の値のみを取得します。構造はat[<インデックス>, <列名>]:

# 注:文字列インデックスは引用符が必要
df.at[4, 'Q1'] # 65
df.at['lily', 'Q1'] # 65 インデックスがnameと仮定
df.at[0, 'name'] # 'Liver'
df.loc[0].at['name'] # 'Liver'
# 指定した列の値に対応する他の列の値を取得
df.set_index('name').at['Eorge', 'team'] # 'C'
df.set_index('name').team.at['Eorge'] # 'C'
# 列の指定インデックスの値を取得
df.team.at[3] # 'C'

同様に、iatはilocと同じく数値インデックスのみサポート:

df.iat[4, 2] # 65
df.loc[0].iat[1] # 'E'

.getは辞書のような操作ができ、値がない場合はデフォルト値を返します(例では0):

df.get('name', 0) # name列
df.get('nameXXX', 0) # 0、デフォルト値を返す
s.get(3, 0) # 93、Seriesはインデックスを渡して特定の値を返す
df.name.get(99, 0) # 'Ben'

式フィルタリング

[]スライスでは式を使用してフィルタリングできます:

df[df['Q1'] == 8] # Q1が8に等しい
df[~(df['Q1'] == 8)] # 8に等しくない
df[df.name == 'Ben'] # 名前がBen
df.loc[df['Q1'] > 90, 'Q1':] # Q1が90より大きい、Q1のみ表示
df.loc[(df.Q1 > 80) & (df.Q2 < 15)] # and関係
df.loc[(df.Q1 > 90) | (df.Q2 < 90)] # or関係
df[df.Q1 > df.Q2]

論理比較関数:

df.eq() # 等しい ==
df.ne() # 等しくない !=
df.le() # 以下 <=
df.lt() # 未満 <
df.ge() # 以上 >=
df.gt() # より大きい >
# すべてaxis{0 or 'index', 1 or 'columns'}をサポート、デフォルトは'columns'
df[df.Q1.ne(89)] # Q1が89に等しくない
df.loc[df.Q1.gt(90) & df.Q2.lt(90)] # and関係 Q1>90 Q2<90

その他の関数:

# isin
df[df.team.isin(['A','B'])] # グループAとBを含む
df[df.isin({'team': ['C', 'D'], 'Q1':[36,93]})] # 複雑なクエリ、他の値はNaN

関数フィルタリング

df[lambda df: df['Q1'] == 8] # Q1が8
df.loc[lambda df: df.Q1 == 8, 'Q1':'Q2'] # Q1が8、Q1 Q2を表示

whereとmask

s.where(s > 90) # 条件に合わない値はNaN
s.where(s > 90, 0) # 条件に合わない値は0
# np.where、80より大きければTrue、そうでなければFalse
np.where(s>80, True, False)
np.where(df.num>=60, '合格', '不合格')

s.mask(s > 90) # 条件に合う値はNaN
s.mask(s > 90, 0) # 条件に合う値は0

query

df.query('Q1 > Q2 > 90') # SQLのwhere文のように直接記述
df.query('Q1 + Q2 > 180')
df.query('Q1 == Q2')
df.query('(Q1<50) & (Q2>40) and (Q3>90)')
df.query('Q1 > Q2 > Q3 > Q4')
df.query('team != "C"')
df.query('team not in ("E","A","B")')
# スペースを含む列名にはバッククォートを使用
df.query('B == `team name`')

# 変数の受け渡しをサポート、例:平均より40点高い
a = df.Q1.mean()
df.query('Q1 > @a+40')
df.query('Q1 > `Q2`+@a')

filter

filterを使用して行名と列名をフィルタリングできます。

df.filter(items=['Q1', 'Q2']) # 2列を選択
df.filter(regex='Q', axis=1) # Qを含む列名
df.filter(regex='e$', axis=1) # eで終わる
df.filter(regex='1$', axis=0) # 正規表現、1を含むインデックス名
df.filter(like='2', axis=0) # インデックスに2を含む
# 2で始まるインデックス、Qを含む列名
df.filter(regex='^2', axis=0).filter(like='Q', axis=1)

結合と行列の追加

列の追加

元のデータが以下のようになっていると仮定:

import pandas as pd
import numpy as np

df = pd.DataFrame({'num_legs': [4, 2], 'num_wings': [0, 2]},
                  index=['dog', 'hawk'])
slen = len(df['num_legs'])

1)直接代入

df['a'] = pd.Series(np.random.randn(slen), index=df.index) # indexを追加することを忘れずに
df['b'] = None # None値の列を追加
df['c'] = [2, 4] # リストデータを追加

2)locメソッド

df.loc[:,'d'] = pd.Series(np.random.randn(slen), index=df.index)
df.loc[:, 'd'] = [2, 4]

3)insertメソッド

insertメソッドの列名は重複不可、更新も不可

df.insert(len(df.columns), 'e', pd.Series(np.random.randn(slen)), index=df.index)
df.insert(len(df.columns), 'ee', [1,2])

4)assignメソッド

assignメソッドのパラメータはSeries、スカラー、リストで、複数列を同時に追加可能

df = df.assign(f=df.num_wings.mean())  # num_wings列の平均値を新しい列fとして使用
df = df.assign(A=df.num_wings.sum(), B=[1,2])  # 列AとBを追加

5)concatメソッド

pd.concat([df, pd.Series(['yes', 'yes']).rename('t')], axis=1) # 列tを追加

行の追加

import pandas as pd
import numpy as np

# 空のDataFrameを作成
df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])

1)locを使用

for i in range(4):
    df.loc[i] = [np.random.randint(-1, 1) for n in range(3)]
    # df.loc[i] = 5 すべての値が5のレコードを追加

2)appendを使用

df.append({'lib': 2, 'qty1': 3, 'qty2': 4}, ignore_index=True)

# appendはDataFrameも直接追加可能
df2 = pd.DataFrame([[1,2,3], [2,3,4]], columns=['lib', 'qty1', 'qty2'])
df.append(df2, ignore_index=True)  # ignore_index=Trueでdf2のインデックスを無視

結合

append() Vs. concat()

DataFrameを連結または結合する場合、一般的に縦方向と横方向の2つの方法があります。縦方向は2つ以上のDataFrameを縦に(上から下へ)1つのDataFrameに連結します。横方向は同じインデックスがある場合、同じインデックス上のすべての列データを結合します。

DataFrameの連結と結合によく使う関数はappend()concat()merge()です。append()は縦方向の連結のみ可能で、concat()merge()は両方可能です。concat()はデフォルトで縦方向連結(append()と同じ効果)、横方向結合にはconcat(axis=1)を使用します。

concat() Vs. merge()

concat()merge()の違いについて説明します。両方とも横縦方向の結合が可能ですが、使用法と出力結果にいくつかの違いがあります。

joinの概念を紹介します。concat()のデフォルトjoin方式はouter join、merge()のデフォルトはinner joinです。もう1つの重要な違いは、concat()はインデックスで結合し、merge()は列ラベルで結合することです。

# outer joinでconcat(デフォルト)
pd.concat([population, unemployment], axis=1)

# inner joinでconcat
pd.concat([population, unemployment], axis=1, join='inner')

merge操作の場合:

# merge()のデフォルトはinner join、パラメータは'how'で'join'ではない
pd.merge(population, unemployment, left_on='ZipCode', right_on='Zip')

# 列がインデックスに設定されている場合、まずreset_index()が必要
population = population.reset_index()
unemployment = unemployment.reset_index()
pd.merge(population, unemployment, left_on='ZipCode', right_on='Zip', how='outer')

join() Vs. concat()

joinには4つの結合方法があります:how='left'how='right'how='inner'how='outer'merge()もこれらすべてのメソッドを持っています。

# joinのデフォルト結合方法はhow='left'
population.join(unemployment)

# rightでjoin
population.join(unemployment, how='right')

joinとconcatは両方ともインデックスで結合するため、対応するインデックスが必要です。concatはjoinと比較してleftとrightの結合方法がありませんが、outerとinnerの結果は同じです:

population.join(unemployment, how='outer')
pd.concat([population, unemployment], join='outer', axis=1)
# 上記2つの結果は同じ

population.join(unemployment, how='inner')
pd.concat([population, unemployment], join='inner', axis=1)
# 上記2つの結果は同じ

append()、concat()、join()、merge()のまとめ

append()

構文:df1.append(df2)

説明:append()は単純に2つのDataFrameを縦に並べます。インデックス不要

concat()

構文:pd.concat([df1, df2])

説明:concat()は複数の行または列を横縦方向に結合でき、innerまたはouterメソッドを使用できます。インデックス必要

join()

構文:df1.join(df2)

説明:join()は複数の結合方法を使用でき、innerとouter以外にleftとrightも使用できます。これらの操作もインデックス必要

merge()

構文:pd.merge([df1, df2])

説明:最も多機能な結合関数。インデックス不要。

merge_ordered()関数

merge_ordered()関数は1つの関数で2つの操作を実行できます:merge()sort_values()

pd.merge_ordered(hardware, software, on=['', ''], suffixes=['', ''], fill_method='ffill')