【Pandas】DataFrame間で重複する列名を取得する【Python】
MAX
MAX999blog
DataFrameを扱っている際に、インデックスとなる列を作成する場合など、複数の列を結合する必要がある時がある。
列名指定でも結合できるし、少しだけ抽象度を上げて列名のリストなどからも結合できる。
1import pandas as pd
2
3df = pd.DataFrame({
4 'A': [1, 2, 3],
5 'B': ['a', 'b', 'c'],
6})
7print(df)
8# A B
9# 0 1 a
10# 1 2 b
11# 2 3 c
A列はint型でB列は文字列型。
文字列として結合する場合、数値型の列には注意が必要。
列の型に関わらず、結合できるようにastype(str)
で文字列として扱う。
1# 列名を指定してアンダースコアで結合
2# A列とB列を結合する
3df['AB'] = df['A'].astype(str) + "_" + df['B'].astype(str)
4print(df)
5# A B AB
6# 0 1 a 1_a
7# 1 2 b 2_b
8# 2 3 c 3_c
今回は間にアンダースコアを入れたが、別になくても文字列の結合はできる。
splitで分割する時のことを考えて、値の中に存在しない文字列で結合してやると、その文字列で分割可能となるため便利。
1df['A'] + "_" + df['B']
2# UFuncTypeError: ufunc 'add' did not contain a loop with signature matching types (dtype('int64'), dtype('<U1')) -> None
A列はint型で”_”は文字列のため、「+」演算子で計算ができない。
結合したい列が3個以上の場合や、特定の列に決まっていない場合など、少し抽象度を上げた処理をしたい場合、結合したい列名のリストなどがあれば、そこから結合できる。
1import pandas as pd
2
3df = pd.DataFrame({
4 'A': [1, 2, 3],
5 'B': ['a', 'b', 'c'],
6 'C': ['x', 'y', 'z']
7})
8print(df)
9# A B C
10# 0 1 a x
11# 1 2 b y
12# 2 3 c z
applyで1行ずつに対してアンダースコアで繋げる。
1# 列名のリストから複数列をまとめて結合する
2cols = ["A", "B", "C"]
3
4# 文字列に変換し、applyで1行ずつアンダースコアで連結
5df['concatenated'] = df[cols].astype(str).apply('_'.join, axis=1)
6print(df)
7# A B C concatenated
8# 0 1 a x 1_a_x
9# 1 2 b y 2_b_y
10# 2 3 c z 3_c_z
上記の処理はapplyを使うので、行数が多くなってくると、applyを使わない場合と比べて処理時間が遅くなってくるのを感じるかもしれない。
処理時間を気にする場合、applyは使わずに、列名を個別で指定して結合する方が処理時間は早い。
1# 列名を指定してアンダースコアで結合
2# A列とB列を結合する
3df['AB'] = df['A'].astype(str) + "_" + df['B'].astype(str)
4
5
6# 列名のリストから複数列をまとめて結合する
7cols = ["A", "B", "C"]
8# 文字列に変換し、applyで1行ずつアンダースコアで連結
9df['concatenated'] = df[cols].astype(str).apply('_'.join, axis=1)