PandasのGroupby集計でつまづいたのでまとめてみた
PandasのGroupby集計でつまづいたのでまとめてみました。
なお、データはKaggleのTitanic train.csvを使っています www.kaggle.com
環境 Windows10、Anaconda ver1.97、python 3.69、jupyter notebook
詰まったのは、groupby()のas_index=Falseの指定です。
まずtrain.csvをKaggleのサイトからダウンロードして読み込みます。
import pandas as pd data1 = pd.read_csv("C:xxxxxxx/train.csv") data1
xxxxx の部分はtrain.csvを入れたパスです。 pwdや、import os のちのos.cwd()で確認ください。
年齢('Age')でグルーピング化して、料金('Fare')を集計、料金('Fare')の降順に並び替え、 料金('Fare')を4分割してグループ名を付けて、4つのグループごとに集計し、構成割合を付けます。
NaN値があるとややこしいので、isnull()で確かめます。 年齢('Age')に177個のNaN値があることがわかります。
data1.isnull().sum()
今回は予測が目的ではないので、NaN値はばっさり削除します。 また、客室('Cabin')や出航地('Embarked')は今回使わないので無視します。
data1_Age_nonNull = data1.dropna(subset=["Age"])
再びNaN値を数えると、ちゃんと年齢('Age')のNaN値はゼロになっていますね。
data1_Age_nonNull.isnull().sum()
年齢('Age')をベースに、料金('Fare')で集計すると88項目に集約されます。 なお、引っかかったのはこちらでして、先に間違いだったコードを記載します。
data2
このままグループ名を適当に付けて、data2に新しくグループ列を作り、qcut()関数で4分割して グループ名をグループ列に入れると、エラーが発生します。
なお、qcut()は「数」をベースに指定の分割を行うことができる関数です。 pandasのcut, qcut関数でビニング処理(ビン分割) | note.nkmk.me
group_names = ['1st','2nd','3rd','4th'] data2['Group'] = pd.qcut(data2['Fare'], 4, labels=group_names) data2
KeyError: 'Fare'
調べたところ、これは、Groupby()の中に、as_index=False を入れなかったため、 データが1次元構造のSeries型になってしまい、列名 料金('Fare')が消えてしまったことが要因のようです。
細かいことは下記の記事をお読みください。
正しいコードは下記のとおりです。
data2 = data1_Age_nonNull.groupby(['Age'], as_index=False)['Fare'].sum().sort_values(by=['Fare'], ascending=False) data2
(参考) 誤ったコードのdata2の型
data2.dtypes
dtype('float64')
正しいコードのdata2の型
data3.dtypes
Group category Fare float64 dtype: object
groupby()の処理をする際、
.groupby(['Age'], as_index=False)
とすることで、二次元構造のDataFrame型を維持することができ、列名 料金('Fare')で集計することが可能となります。 Series型にしてしまうと、列名 料金('Fare')が消えてしまうのです。
正しいコードで記載した後は、
group_names = ['1st','2nd','3rd','4th'] data2['Group'] = pd.qcut(data2['Fare'], 4, labels=group_names) data2
data3 = data2.groupby(['Group'], as_index=False)['Fare'].sum().sort_values(by=['Fare'], ascending=True) data3
data3['SalesRatio'] = data3['Fare'] / data3['Fare'].sum() data3
以上になります、最後までお読みいただきありがとうございました。