わけあって下記のようにgroupをグループ化して、指定した列をユニーク数分新しいカラムを用意して横持ちに変換する必要がでてきました。
今回の例でいう新しいカラムを作成するcol1,col2以外はグループ毎に同じデータが入っているという条件です。
メソッドでさくっとできるかなと考えていたのですが、
メソッドではできなさそうなので、自分で処理を作成しました。
同じコードを書く必要が出てきたときに備えてメモを残しておきます。
データ用意
import pandas as pd
data = {
'group': ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C' ],
'other_col': ['AA', 'AA', 'AA', 'BB', 'BB', 'CC', 'CC', 'CC', 'CC' ],
'col1': list(range(1, 10)),
'col2': list(range(11, 20))
}
df = pd.DataFrame(data)
df
この状態でグループ化をすると下記のようなに
グループ名とindexesの辞書を作成してくれることを利用して今回はデータ整理をしました。
groups
df.groupby('group').groups
# {'A': [0, 1, 2], 'B': [3, 4], 'C': [5, 6, 7, 8]}
変更するコード
groups = df.groupby('group').groups
new_df = pd.DataFrame()
# 項目+Numberで項目を作成したいカラム
target_columns = ['col1', 'col2']
# それ以外のカラムを作成
other_column = [x for x in df.columns.tolist() if x not in target_columns]
max_length = 0
for group, indexes in groups.items():
# 最後に並び替えをさせるのに最大作成された項目数を記録
length = len(indexes)+1
if length > max_length:
max_length = length
columns = other_column.copy()
values = df[other_column].iloc[indexes[0], :].values.tolist()
for target_column in target_columns:
columns += [f'{target_column}_{x}' for x in range(1, length)]
values += df.iloc[indexes, :][target_column].T.tolist()
record_df = pd.DataFrame([values], columns=columns)
new_df = pd.concat([new_df, record_df], axis=0)
# ここまでで必要な情報はそろっているが並びがよくないので以下で整理
sorted_columns = other_column.copy()
for target_column in target_columns:
sorted_columns += [f'{target_column}_{x}' for x in range(1, max_length)]
sorted_df = new_df[sorted_columns]
sorted_df