質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

解決済

Pandas.DataFrameのデータ構造を変えたい(縦持ちから横持ちへ)

CookieM
CookieM

総合スコア6

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

2回答

0リアクション

0クリップ

220閲覧

投稿2022/08/31 10:51

前提

python 3.7.3
Anaconda Jupyter Notebook

実現したいこと

元データイメージ
イメージ説明
加工後データイメージ
「2019から2020にかけてID1はElemがAからBに変わった」と読めるような横持ちのデータにしたい。
イメージ説明

発生している問題・エラーメッセージ

エラーはありません

該当のソースコード

python

import pandas as pd import numpy as np import itertools #元データ(上記元データイメージと同じもの) df = pd.DataFrame() df["Year"] = ["2019","2020","2021","2019","2020","2021","2019","2020","2021"] df["ID"] = [1,1,1,2,2,2,3,3,3] df["Elem"] = ["A","B","A","C","B","A","A","C","B"] #のちに結合する枠として、Yearの組み合わせをDataFrameの形で定義しておく year = df["Year"].drop_duplicates() year_list = year.sort_values().tolist() ptn = itertools.combinations(year_list, 2) #IDの2つの組み合わせを設定 flame_df = pd.DataFrame([i for i in ptn], columns=["基準","比較"]) """ 基準 比較 0 2019 2020 1 2019 2021 2 2020 2021 """ #一意のIDをリスト形式で保持 ids = df["ID"].drop_duplicates() ids_list = ids.sort_values().tolist() #本処理 output = pd.DataFrame() for i in ids_list: #idごとに処理を回す tmp = flame_df.copy() tmp["ID"] = i #該当IDにおける基準年のElemをflame_dfにマージ std_merged = pd.merge(tmp, df[df["ID"]==i], how='left', left_on=['基準','ID'], right_on=['Year','ID']).drop(columns='Year') #該当IDにおける比較年のElemをflame_dfにマージ both_merged = pd.merge(std_merged, df[df["ID"]==i], how='left', left_on=['比較','ID'], right_on=['Year','ID']).drop(columns='Year') output = pd.concat([output, both_merged]) output.rename(columns={"Elem_x":"基準Elem", "Elem_y":"比較Elem"}, inplace=True) output """ 基準 比較 ID 基準Elem 比較Elem 0 2019 2020 1 A B 1 2019 2021 1 A A 2 2020 2021 1 B A 0 2019 2020 2 C B 1 2019 2021 2 C A 2 2020 2021 2 B A 0 2019 2020 3 A C 1 2019 2021 3 A B 2 2020 2021 3 C B """

試したこと

縦持ちデータを横持にする際一般的にはpivot_tableを用いますが、
今回加工したい形に対応するaggfuncがないため、地道にやるしかないと思い、
上記のコードで実装してみました。

ただ実現はできたものの、IDの規模の規模が大きい場合、
IDごとに処理をループするこの書き方ではパフォーマンスに懸念があり・・・
より効率的な記述の作法がございましたらご意見をいただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。