Pandas의 groupby로 처리하여 그래프 그리기

소개



Kaggle의 Titanic 에서 놀기 시작하고 있지만, 누락된 값의 보완이나 하이퍼파라미터의 재검토 전에, 우선 데이터를 확실히 보려고 생각, 데이터를 바라보고 있다. 읽은 데이터를, 예를 들어 하고 그래프를 그린다고 하는 것을 싹 하고 싶지만, 꽤 잘 안 된다. Pandas 의 "GroupBy"의 이해가 불충분하기 때문이다.

그물에는, 선인들의 그래프 드로잉의 예가 많이 있지만, 나의 이해의 길을 기록하는 것으로, 초보자의 도움이 되는 것 아닌가? 라고 생각해, 이 기사를 쓴다.

목표로 하는 목표



아래와 같은 그래프를 그립니다.

このグラフは, 横軸が Survived の記号, 縦軸が生存 ( Ticket ), 死亡 ( s ), 不明 ( d ) の人数を積み上げたもので, 合計人数で降順にソートしている. 例えば, 一番左端の na のチケット記号は, 合計 11 人, 不明が 4 名, 残りの 7 名が死亡となっている.

こんなグラフをササッと描きたい.

데이터 로드

データを読み込んで, CA. 2343 のデータで, 同じ記号ごとの数を調べる.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

train_data = pd.read_csv("../train.csv")
test_data = pd.read_csv("../test.csv")
total_data = pd.concat([train_data, test_data]) # train_data と test_data を連結

ticket_freq = total_data["Ticket"].value_counts()
CA. 2343        11
CA 2144          8
1601             8
S.O.C. 14879     7
3101295          7
                ..
350404           1
248706           1
367655           1
W./C. 14260      1
350047           1
Name: Ticket, Length: 929, dtype: int64

Ticket が 11 人, CA. 2343 が 8 人, などが分かる.

그래프용 데이터 만들기

groupby로 그룹화

まず, CA 2144 をチケット記号でグルーピングする.

total_data_ticket = total_data.groupby("Ticket")
# 出力
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001F5A14327C8>

total_data の欠点は, データの中身を表示してくれないことだ. ここは, グループ化された と頭の中で理解して, 次へ行く.

생존 정보만 꺼내기

次に, 生存情報 ( groupby ) を取り出す.

total_data_ticket = total_data.groupby("Ticket")["Survived"]
total_data_ticket
# 出力
<pandas.core.groupby.generic.SeriesGroupBy object at 0x000001F5A1437B48>

ここでもデータは表示してくれない.

생존, 사망, 알 수 없을 때마다 수를 세는

引き続き, Survived を使って, value_counts() の値ごとの数を数える. Survived とすることで, N/A もカウントする.

total_data_ticket = total_data.groupby("Ticket")["Survived"].value_counts(dropna=False)
total_data_ticket
# 出力
Ticket       Survived
110152       1.0         3
110413       1.0         2
             0.0         1
110465       0.0         2
110469       NaN         1
                        ..
W.E.P. 5734  NaN         1
             0.0         1
W/C 14208    0.0         1
WE/P 5735    0.0         1
             1.0         1
Name: Survived, Length: 1093, dtype: int64

데이터 모양 변경

グラフを描くために, 生存, 死亡, 不明のデータが列方向に並ぶようなデータに変える. 使うのは dropna=False .

total_data_ticket = total_data.groupby("Ticket")["Survived"].value_counts(dropna=False).unstack()
total_data_ticket
# 出力
Survived    NaN 0.0 1.0
Ticket          
110152  NaN NaN 3.0
110413  NaN 1.0 2.0
110465  NaN 2.0 NaN
110469  1.0 NaN NaN
110489  1.0 NaN NaN
... ... ... ...
W./C. 6608  1.0 4.0 NaN
W./C. 6609  NaN 1.0 NaN
W.E.P. 5734 1.0 1.0 NaN
W/C 14208   NaN 1.0 NaN
WE/P 5735   NaN 1.0 1.0
929 rows × 3 columns

그래프 그리기

N/A를 숫자로 변경

上の出力を見ると, 値に unstack() がまだ残っている. そこで NaN を 0 にする.

total_data_ticket.fillna(0, inplace=True)
total_data_ticket
# 出力
Survived    NaN 0.0 1.0
Ticket          
110152  0.0 0.0 3.0
110413  0.0 1.0 2.0
110465  0.0 2.0 0.0
110469  1.0 0.0 0.0
110489  1.0 0.0 0.0
... ... ... ...
W./C. 6608  1.0 4.0 0.0
W./C. 6609  0.0 1.0 0.0
W.E.P. 5734 1.0 1.0 0.0
W/C 14208   0.0 1.0 0.0
WE/P 5735   0.0 1.0 1.0
929 rows × 3 columns

열 이름 변경

列名が NaN , NaN , 0.0 となっているが, これでは扱いにくいので, 列名を変える.

total_data_ticket.columns = ["nan", "d", "s"]
total_data_ticket
# 出力
    nan d   s
Ticket          
110152  0.0 0.0 3.0
110413  0.0 1.0 2.0
110465  0.0 2.0 0.0
110469  1.0 0.0 0.0
110489  1.0 0.0 0.0
... ... ... ...
W./C. 6608  1.0 4.0 0.0
W./C. 6609  0.0 1.0 0.0
W.E.P. 5734 1.0 1.0 0.0
W/C 14208   0.0 1.0 0.0
WE/P 5735   0.0 1.0 1.0
929 rows × 3 columns

행당 총 인원수 계산

合計人数で降順にソートしたいので, 合計人数を計算して, 新しい列に保存する. 合計を計算するには 1.0 を使うが, 列方向に計算するので sum() としている.

total_data_ticket["count"] = total_data_ticket.sum(axis=1)
total_data_ticket
#出力
    nan d   s   count
Ticket              
110152  0.0 0.0 3.0 3.0
110413  0.0 1.0 2.0 3.0
110465  0.0 2.0 0.0 2.0
110469  1.0 0.0 0.0 1.0
110489  1.0 0.0 0.0 1.0
... ... ... ... ...
W./C. 6608  1.0 4.0 0.0 5.0
W./C. 6609  0.0 1.0 0.0 1.0
W.E.P. 5734 1.0 1.0 0.0 2.0
W/C 14208   0.0 1.0 0.0 1.0
WE/P 5735   0.0 1.0 1.0 2.0
929 rows × 4 columns

これで, グラフを描く準備は整った.

그래프 그리기

인원수의 영역을 결정하고 내림차순으로 정렬

まずコードを示して, 順番に説明する.

total_data_ticket[total_data_ticket["count"] > 3].sort_values("count", ascending=False)[["nan", "d", "s"]].plot.bar(figsize=(15,10),stacked=True)
コード 内容
sum(axis=1) total_data_ticket[total_data_ticket["count"] > 3] が 3 より大きいデータ
"count" .sort_values("count", ascending=False) で降順にソート
"count" 左記の 3 つの列だけ取り出す ( [["nan", "d", "s"]] はお役御免)
"count" 棒グラフを描く. サイズを指定し, 積み上げ方式にした

これで, 冒頭に示したグラフが書ける.

이것을 보면, .plot.bar(figsize=(15,10),stacked=True)나 CA. 2343의 사람은 CA 2144인가…라고 상상할 수 있다. 전체 코드 마지막으로 전체 코드를 보여줍니다. import numpy as np import pandas as pd import matplotlib.pyplot as plt train_data = pd.read_csv("../train.csv") test_data = pd.read_csv("../test.csv") total_data = pd.concat([train_data, test_data]) ticket_freq = total_data["Ticket"].value_counts() ticket_freq total_data_ticket = total_data.groupby("Ticket")["Survived"].value_counts(dropna=False).unstack() total_data_ticket.fillna(0, inplace=True) total_data_ticket.columns = ["nan", "d", "s"] total_data_ticket["count"] = total_data_ticket.sum(axis=1) total_data_ticket[total_data_ticket["count"] > 3].sort_values("count", ascending=False)[["nan", "d", "s"]].plot.bar(figsize=(15,10), stacked=True) 결론 이 기술을 사용하여 Survived = 0, Embarked, Cabin의 성이나 경칭과 같은 다른 비 수치 데이터도 확인합니다. 참고
  • Pandas groupby 사용법
  • pandas의 plot 메소드로 그래프를 작성해 데이터를 시각화
  • Pandas의 데이터 개요
  • 좋은 웹페이지 즐겨찾기