データを縦持ちから横持ちに変換する方法について解説します。 横持ちデータを縦持ちデータに変換する方法についてはこちらでまとめています。
1.そもそも縦持ちと横持ちとは
縦持ちとは縦に長いデータで以下のようなデータのことです。
氏名 | 科目 | 点数 |
---|---|---|
A君 | 数学 | 100 |
A君 | 国語 | 70 |
A君 | 英語 | 60 |
A君 | ドイツ語 | 60 |
B君 | 数学 | 60 |
B君 | 国語 | 50 |
B君 | 英語 | 50 |
B君 | アラビア語 | 60 |
一方、横持ちとは横に長いデータで以下のようなデータです。
氏名 | 数学 | 国語 | 英語 | ドイツ語 | アラビア語 |
---|---|---|---|---|---|
A君 | 100 | 70 | 60 | 60 | NaN |
B君 | 60 | 50 | 50 | NaN | 60 |
上記の例ですと、横持ちの方がすっきりしていて、良いように感じますが、必ずしもそうではありません。どのようなデータの場合、縦持ちの方が良いか後述します。まずは、Pandasで縦持ちデータを横持ちに変換する方法について記載します。
2.縦持ちを横持ちに変換する方法
以下の通りです。まずは縦持ちのサンプルデータを作成します。
df_score_vertical = pd.DataFrame([['A君','数学',100], ['A君','国語',70], ['A君','英語',60], ['A君','ドイツ語',60], ['B君','数学',60], ['B君','国語',50], ['B君','英語',50], ['B君','アラビア語',60]], columns=['氏名','科目','点数'])
以下のコードで横持ちに変換できます。
df_score_horizontal = pd.pivot_table(df_score_vertical, index=['氏名'], columns=['科目'], values='点数', fill_value=0)
上記のコードを実行すると以下のようなDataFrameが作成されます。
カラム名が2段になっていますし、「氏名」がIndexになってしまっています。こうならないようにするために以下のようなコードを実行します。多少強引ですが、カラムの貼り直しをしています。
df_score_horizontal = pd.pivot_table(df_score_vertical, index=['氏名'], columns=['科目'], values='点数', fill_value=0).reset_index() df_score_horizontal.columns = df_score_horizontal.columns.to_list()
上記を実行することで以下のようなDataFrameができます。たぶん、多くの人が欲しい結果ではないでしょうか。
3.縦持ちデータの方が良い例
極端な例ですが、以下のようなデータの場合は横持ちにしてしまうと無駄に表が大きくなってしまいます。
<横持ちの場合>
氏名 | フランス語 | ドイツ語 | アラビア語 | ベトナム語 |
---|---|---|---|---|
A君 | 100 | NaN | NaN | NaN |
B君 | NaN | 50 | NaN | NaN |
C君 | NaN | NaN | NaN | 80 |
B君 | NaN | NaN | 50 | NaN |
欠損値だらけで無駄が多いです。上記のようなデータを疎行列(スパースマトリックス)といいます。以下のように縦持ちにすることですっきりして、データサイズも削減できます。
縦持ちで表現するとスマートです。
氏名 | 科目 | 点数 |
---|---|---|
A君 | フランス語 | 100 |
B君 | ドイツ語 | 50 |
C君 | ベトナム語 | 80 |
D君 | アラビア語 | 50 |
関連記事
SQLで縦持ちデータを横持ちデータに変換する方法についてもまとめたので、良ければ参考にしてください。
book-read-yoshi.hatenablog.com