DataFrameのカラムの順番を変える方法

DataFrameの列数が多くなってくると、カラムの位置を変えたくなることがあります。2種類の方法をご紹介します。

1つ目はpandas.DataFrame.reindexです。
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.reindex.html

2つ目はpandas.DataFrame.insertを使います。
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html

関数reindexで変える

関数reindexを使ってカラムの順番を変えます。元データのDataFrameはカラムがA, B, C”でIndexが”X, Y, Z”とするデータを使っています。

columns引数かaxis引数を使えば、カラムの順番を変えることができます。引数の指定をしないとデータが欠損値になります。

# 元データのDataFrameを作成する。
df = pd.DataFrame(
        data=[[0, 1, 2], [3, 4, 5], [6, 7, 8]],
        index=['X', 'Y', 'Z'],
        columns=['A', 'B', 'C'],
        )

print(df)
#    A  B  C
# X  0  1  2
# Y  3  4  5
# Z  6  7  8


# columns引数でカラムの順番を変える。
df_new = df.reindex(columns=['B', 'C', 'A'])

print(df_new)
#    B  C  A
# X  1  2  0
# Y  4  5  3
# Z  7  8  6


# axis引数でカラムの順番を変える。
df_new = df.reindex(['B', 'C', 'A'], axis='columns')

print(df_new)
#    B  C  A
# X  1  2  0
# Y  4  5  3
# Z  7  8  6


# 引数を指定しないと欠損値になる。
df_new = df.reindex(['B', 'C', 'A'])

print(df_new)
#     A   B   C
# B NaN NaN NaN
# C NaN NaN NaN
# A NaN NaN NaN

上でカラムの順番を変える例を示しましたが、関数reindexはIndexの順番も変えられます。

# index引数でIndexの順番を変える。
df_new = df.reindex(index=['Y', 'Z', 'X'])

print(df_new)
#    A  B  C
# Y  3  4  5
# Z  6  7  8
# X  0  1  2


# axis引数でIndexの順番を変える。
df_new = df.reindex(['X', 'Z', 'Y'], axis='index')

print(df_new)
#    A  B  C
# X  0  1  2
# Z  6  7  8
# Y  3  4  5

順番変更ではないのですが、補足情報です。DataFrameに存在しないカラム名やIndex名を引数に入れてしまうと欠損値になります。欠損値ではなく初期値を入れたい場合はfill_value引数を使えば回避できます。

# 存在しないカラム名を指定すると欠損値になる。
df_new = df.reindex(columns=['B', 'C', 'D'])

print(df_new)
#    B  C   D
# X  1  2 NaN
# Y  4  5 NaN
# Z  7  8 NaN


# 存在しないカラム名を追加挿入して、初期値を埋めたい場合はfill_value引数を使う。
df_new = df.reindex(columns=['B', 'C', 'D'], fill_value=0)

print(df_new)
#    B  C  D
# X  1  2  0
# Y  4  5  0
# Z  7  8  0

関数insertで変える

関数insertを使って、カラムの順番を変えます。処理の流れはDataFrameから関数popでカラムを取り除いて、関数insertで指定した位置に挿入する形です。サンプルコードを見てみましょう。カラムの順番が”A, B, C”になっているところを”C”カラムを2番目に変えてみます。

関数popと関数insertの仕様はこちらです。
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pop.html
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html

# 元データのDataFrameを作成する。
df = pd.DataFrame(
        data=[[0, 1, 2], [3, 4, 5], [6, 7, 8]],
        index=['X', 'Y', 'Z'],
        columns=['A', 'B', 'C'],
        )

print(df)
#    A  B  C
# X  0  1  2
# Y  3  4  5
# Z  6  7  8


# DataFrameからCカラムを取り除く。
s = df.pop('C')

print(s)
print(type(s))

# 関数popの戻り値はpandas.Seriesになる。
# X    2
# Y    5
# Z    8
# Name: C, dtype: int64
# <class 'pandas.core.series.Series'>

# 関数insertで指定した位置に、関数popの戻り値のCカラムを挿入する。
df.insert(1, s.name, s)

print(df)
#    A  C  B
# X  0  2  1
# Y  3  5  4
# Z  6  8  7

補足情報です。関数insertですでにあるカラム名を挿入しようとするとValueErrorになります。その場合はallow_duplicates=Trueを引数に追加します。

# 再度Cカラムを挿入すると、ValueErrorになる。
# 下記コードだと、次のエラーになる。「ValueError: cannot insert C, already exists」
df.insert(1, s.name, s)

# 同じ名前のカラムを挿入する場合は、allow_duplicates引数を指定する。
df.insert(1, s.name, s, allow_duplicates=True)

print(df)
#    A  C  C  B
# X  0  2  2  1
# Y  3  5  5  4
# Z  6  8  8  7