note.nkmk.me

pandas.DataFrameの行と列を入れ替える(転置)

Date: 2018-01-12 / Modified: 2019-12-22 / tags: Python, pandas

pandas.DataFrameの行と列を入れ替えたい(=転置させたい)場合は、T属性かtranspose()メソッドを使う。

どちらの方法も元のオブジェクトは変更されず、行と列が入れ替わった(=転置された)新たなオブジェクトが返される。各列のデータ型dtypeによってはコピーではなくビューが生成され、元のオブジェクトと転置されたオブジェクトの一方の値を変更するともう一方の値も変更されるので注意。

以下の内容について説明する。

  • pandas.DataFrame.T
  • pandas.DataFrame.transpose()
  • 元のオブジェクト自体を変更
  • 型変換(キャスト)が行われる場合
  • ビューとコピー

NumPy配列ndarrayや二次元リスト(リストのリスト)の転置については以下の記事を参照。

スポンサーリンク

pandas.DataFrame.T

T属性で、転置したpandas.DataFrameを取得できる。

import pandas as pd

df = pd.DataFrame({'X': [0, 1, 2], 'Y': [3, 4, 5]}, index=['A', 'B', 'C'])
print(df)
#    X  Y
# A  0  3
# B  1  4
# C  2  5

print(df.T)
#    A  B  C
# X  0  1  2
# Y  3  4  5

pandas.DataFrame.transpose()

transpose()メソッドも同様。

print(df.transpose())
#    A  B  C
# X  0  1  2
# Y  3  4  5

元のオブジェクト自体を変更

元のオブジェクト自体を変更するinplaceのような引数は用意されていない。新たなオブジェクトを生成したくない場合は元のオブジェクト自体に代入すればよい。

df = df.T
print(df)
#    A  B  C
# X  0  1  2
# Y  3  4  5

型変換(キャスト)が行われる場合

pandas.DataFrameは各列ごとにデータ型dtypeが設定されている。

すべての列が同じデータ型の場合はTtranspose()で転置してもそのままのデータ型。

df = pd.DataFrame({'X': [0, 1, 2], 'Y': [3, 4, 5]}, index=['A', 'B', 'C'])
print(df)
#    X  Y
# A  0  3
# B  1  4
# C  2  5

print(df.dtypes)
# X    int64
# Y    int64
# dtype: object

print(df.T)
#    A  B  C
# X  0  1  2
# Y  3  4  5

print(df.T.dtypes)
# A    int64
# B    int64
# C    int64
# dtype: object

各列が異なるデータ型だと型変換(キャスト)が行われる。例えば、転置した結果、整数intと浮動小数点数floatが混在する列が生じると、その列のデータ型はfloatとなる。

df_mix = pd.DataFrame({'col_int': [0, 1, 2], 'col_float': [0.1, 0.2, 0.3]}, index=['A', 'B', 'C'])
print(df_mix)
#    col_int  col_float
# A        0        0.1
# B        1        0.2
# C        2        0.3

print(df_mix.dtypes)
# col_int        int64
# col_float    float64
# dtype: object

print(df_mix.T)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.1  0.2  0.3

print(df_mix.T.dtypes)
# A    float64
# B    float64
# C    float64
# dtype: object

再度転置しても元には戻らない。データ型を変換するにはastype()を適用する必要がある。

print(df_mix.T.T)
#    col_int  col_float
# A      0.0        0.1
# B      1.0        0.2
# C      2.0        0.3

print(df_mix.T.T.dtypes)
# col_int      float64
# col_float    float64
# dtype: object

文字列strなどが要素である列はオブジェクト型となる。

df_mix2 = pd.DataFrame({'col_int': [0, 1, 2], 'col_float': [0.1, 0.2, 0.3], 'col_str': ['a', 'b', 'c']},
                       index=['A', 'B', 'C'])
print(df_mix2)
#    col_int  col_float col_str
# A        0        0.1       a
# B        1        0.2       b
# C        2        0.3       c

print(df_mix2.dtypes)
# col_int        int64
# col_float    float64
# col_str       object
# dtype: object

print(df_mix2.T)
#              A    B    C
# col_int      0    1    2
# col_float  0.1  0.2  0.3
# col_str      a    b    c

print(df_mix2.T.dtypes)
# A    object
# B    object
# C    object
# dtype: object

print(df_mix2.T.T)
#   col_int col_float col_str
# A       0       0.1       a
# B       1       0.2       b
# C       2       0.3       c

print(df_mix2.T.T.dtypes)
# col_int      object
# col_float    object
# col_str      object
# dtype: object

pandasのデータ型dtypeastype()についての詳細は以下の記事を参照。

ビューとコピー

すべての列のデータ型が同じである場合、Ttranspose()はビューを返す。

元のオブジェクトとビューをオブジェクトはメモリを共有するので、一方の要素を変更するともう一方も変更される。

df = pd.DataFrame({'X': [0, 1, 2], 'Y': [3, 4, 5]}, index=['A', 'B', 'C'])
print(df)
#    X  Y
# A  0  3
# B  1  4
# C  2  5

df_T = df.T
print(df_T)
#    A  B  C
# X  0  1  2
# Y  3  4  5

df_transpose = df.transpose()
print(df_transpose)
#    A  B  C
# X  0  1  2
# Y  3  4  5

df.at['A', 'X'] = 100
print(df)
#      X  Y
# A  100  3
# B    1  4
# C    2  5

print(df_T)
#      A  B  C
# X  100  1  2
# Y    3  4  5

print(df_transpose)
#      A  B  C
# X  100  1  2
# Y    3  4  5

列ごとにデータ型dtypeが異なる場合、Ttranspose()はコピーを生成する。転置されたオブジェクトは新たなメモリ領域を確保するので、一方の値を変更してももう一方はそのまま。

df_mix = pd.DataFrame({'col_int': [0, 1, 2], 'col_float': [0.1, 0.2, 0.3]}, index=['A', 'B', 'C'])
print(df_mix)
#    col_int  col_float
# A        0        0.1
# B        1        0.2
# C        2        0.3

df_mix_T = df_mix.T
print(df_mix_T)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.1  0.2  0.3

df_mix_transpose = df_mix.transpose()
print(df_mix_transpose)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.1  0.2  0.3

df_mix.at['A', 'col_int'] = 100
print(df_mix)
#    col_int  col_float
# A      100        0.1
# B        1        0.2
# C        2        0.3

print(df_mix_T)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.1  0.2  0.3

print(df_mix_transpose)
#              A    B    C
# col_int    0.0  1.0  2.0
# col_float  0.1  0.2  0.3

その後の処理で転置した方しか使わないのであれば特に気にしなくてもよいが、すべての列のデータ型が同じ場合に元のオブジェクトと転置したオブジェクトを別々に扱いたい場合、Tではcopy()で明示的にコピーを生成する。transpose()では引数copyTrueとするとコピーが生成される。

df = pd.DataFrame({'X': [0, 1, 2], 'Y': [3, 4, 5]}, index=['A', 'B', 'C'])
print(df)
#    X  Y
# A  0  3
# B  1  4
# C  2  5

df_T_copy = df.T.copy()
print(df_T_copy)
#    A  B  C
# X  0  1  2
# Y  3  4  5

df_transpose_copy = df.transpose(copy=True)
print(df_transpose_copy)
#    A  B  C
# X  0  1  2
# Y  3  4  5

df.at['A', 'X'] = 100
print(df)
#      X  Y
# A  100  3
# B    1  4
# C    2  5

print(df_T_copy)
#    A  B  C
# X  0  1  2
# Y  3  4  5

print(df_transpose_copy)
#    A  B  C
# X  0  1  2
# Y  3  4  5

transpose()の引数copyのデフォルトはFalseで、可能な場合はコピーではなくビューを生成する。上の例のように列ごとにデータ型dtypeが異なるときはデフォルト(copy=False)であってもコピーが生成される。必ずビューとなるわけではない。

pandasにおけるビューとコピーについての詳細は以下の記事を参照。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事