はじめてのPythonによるDataFrame処理
データ分析するためのツールの代表といえばExcelですが、複雑な処理をしたい場合にはExcelでは難しくなってきます。
そんな時はPythonの出番です。Pythonでのデータ操作を使いこなせば、どんな複雑な処理であっても自由自在にデータ分析することができます。
本記事ではそんなPythonでデータを扱うための入門編として、その基本操作について整理しました。
なお、開発環境はJupyter notebook、もしくはJupyterLabを想定しています。
データ分析するならば必須に近い開発環境ですので、もし手元に無い場合は以下の記事などを参考に導入することをオススメします。
(無料で、特にユーザー登録なども不要です。)
Pythonにおけるデータの形式「データフレーム」
まず、Pythonでデータ分析をするならば何はともあれ必要なのが「pandas」というライブラリです。
これなくしてデータ分析はありません。
そして、pandasにおける表形式のデータのことをデータフレーム(DataFrame)と呼びます。
Pythonでのデータ分析をマスターするには、このpandasのデータフレーム操作の会得が必要不可欠です。
ということで、Pythonの開発環境を起動したら何はともあれ以下のようにpandasを読み込みましょう。
1 |
import pandas as pd |
「import pandas」は「このプログラム上ではpandasライブラリを使います」という宣言になります。
「as pd」は、「pdと書いたらpandasだと判断してください」という意味で、こうする事によりソースコード上でいちいち「pandas」と書かなければいけないところを「pd」の2文字で済むようになります。
一般的にはas pdまで記載しておく事が多いです。
データフレームの作成
それでは、早速データフレームを取り扱っていきます。
今回は以下のCSVを読み込んで、それをデータフレームにします。
CSVを読み込むにはread_csvメソッドを使います。
今回は、読み込んだデータフレームを以下のようにdf_scoreという変数に格納してみます。
1 |
df_score = pd.read_csv("成績データ.csv") |
これを実行すると・・・
上の例のように、今作成した変数名df_scoreとだけ書いてプログラムを実行すれば、そのまま「df_score」の中身がJupyter上に表示されます。
ちなみに、デフォルトでは1行目がカラム名と判断されます。
それが嫌な場合(1行目からデータが入っている場合)は、引数にheader=Noneを追加すればOKです。
また、特定の列をインデックスにしたい時は、引数にindex_col=【インデックスにしたい列名】を指定すればOKです。
今回は、名前をインデックスにした方が良さそうなので、
1 |
df_score = pd.read_csv("成績データ.csv",index_col="名前") |
としてCSVを読み込むと・・・
名前がインデックスになっているようです。
それでは、今回はこのデータをいろいろと操作していきます。
うまく読み込めない場合は文字コードがおかしい可能性があります。
この場合はread_csvの引数にencoding=”shift_jis”やencoding=”cp932″など文字コードを指定するとうまく読み込めるようになる場合があります。
データの抽出
これでCSVをPythonに読み込めましたので、お次は欲しいデータを部分抽出してみます。
今回扱うサイズくらいなら全部目で見ても良いのですが、何万行、何十万行といったデータだと全部見ていられないので、「欲しいデータの抽出」の方法を知る必要があります。
任意の行・列の抽出
まずは任意の列だけ見たい場合。
例えば理科のデータだけ見たいなら以下のように書きます。
1 |
df_score["理科"] |
非常にシンプルです。結果を見ると・・・
理科のデータのみ抽出できているようです。
では、次は任意の行だけ見たい場合。
例えばDさんのデータだけ見たいなら以下のようにします。
1 |
df_score.loc["D"] |
行をピックアップする場合は、このように.locを使います。結果は・・・
Dさんの結果だけになっています。
それでは、行と列をどちらも指定したい場合。
例えば、Fさんの英語の点数だけ見たいなら、上の2つを組み合わせて以下のようにします。
1 |
df_score["英語"].loc["F"] |
実行すると・・・
Fさんの英語の点数がわかりました。
ちなみに、df_score.loc[“F”][“英語”]の順番でもOKです。
また、これらは条件が複数あってもOKです。
例えば、BさんとEさんの国語と社会の点数をピックアップしたいなら、
1 |
df_score[["国語","社会"]].loc[["B","E"]] |
これで大丈夫です。結果は・・・
この例のように、条件を複数指定する場合はカッコが二重になるので気をつけましょう。
以上が任意のデータを取得する方法でした。
条件を満たす行の抽出
次は条件を満たすデータの抽出です。
Excelで言う「フィルター」に当たります。
先ほどはカラムやインデックスの名称で条件指定しましたが、今度は「○○カラムが■■である行」という条件で抽出します。
例えば、「性別カラムが男性である行」だけ抽出してみます。
1 |
df_score[df_score["性別"]=="男性"] |
こうすると、df_scoreの「性別」列が「男性」の行だけを抽出する、という意味になります。
「==」は「イコール」の意味です。2つ重ねる必要があるのでご注意ください。
結果を見ると・・・
データが男性だけになっていますね。
また、数値を使って絞り込むこともできます。英語の点数が80点以上の列だけ抽出するには、
1 |
df_score[df_score["英語"]>=80] |
と書きます。「>=」は「大なりイコール」の意味です。結果を見ると・・・
英語が80点以上のデータだけ取れていますね。
また、条件を複数にすることも簡単です。
「女性で、かつ国語が60点以下」のデータを取りたいのなら、
1 |
df_score[(df_score["性別"]=="女性")&(df_score["国語"]<=60)] |
と、「<=」(小なりイコール)を使い、条件は「&」を並べて書けば・・・
想像通りにデータを抽出することができました。
このようにすれば、どんな条件でも簡単にフィルタリングすることができます。
この章の最後に、Pythonで使える比較演算子と論理演算子について整理しておきます。
Pythonで使える比較演算子
2つの変数の関係を比較する時に使う記法です。
a == b | aとbは等しい |
---|---|
a != b | aとbは異なる |
a < b | aはb未満(小なり) |
a <= b | aはb以下(小なりイコール) |
a > b | aはbより大きい(大なり) |
a >= b | aはb以上(大なりイコール) |
Pythonで使える論理演算子
条件を指定するときの記法です。
a & b | aかつb。 |
---|---|
a | b | aもしくはb。 |
~a | a以外。 |
データの集計
合計値、平均値、要素数・・・など、数値を集計したい時の方法です。
列ごとの集計
今回の例で言えば、例えば科目別の平均点なんかは知りたいところです。
このように列ごとの平均点を集計したい場合は、以下のように書くだけでOKです。
1 |
df_score.mean() |
すると・・・
非常に簡単ですね。このようにデータフレームに.mean()と付けるだけで列ごとの平均値が計算されます。
行ごとの集計
お次は行ごとの集計です。今度は学生ごとの合計点数を見てみましょう。
それには以下のようにします。
1 |
df_score.sum(axis=1) |
このように行ごとの集計を行いたい場合は、先ほどのカッコの中にaxis=1を指定しましょう。
そして、今度は合計点数なのでmeanではなくsumになります。
これで学生別の合計点も取得できました。
これ以外にも、データフレームの集計関数は色々と準備されていますので、整理しておきます。
データフレームの集計に使える関数
いずれも、データフレーム名の後にくっ付けるだけで列ごとの集計できます。
また、()の中にaxis=1と書くと行ごとの集計となります。
.sum() | 合計値 |
---|---|
.mean() | 平均値 |
.max() | 最大値 |
.median() | 中央値 |
.min() | 最小値 |
.count() | 要素数(空っぽでないセルの数) |
列ごとの色々な集計結果を一気に出す
実は、様々な統計量を一気に算出することもできます。
それにはdescribeメソッドを使います。
1 |
df_score.describe() |
結果は・・・
これだけで、要素数、平均値、標準偏差、最小値、第1四分位数、中央値、第3四分位数、最大値がカラムごとに一気に計算できます。
ざっとデータの全体像を確認したいという場合はdescribeを使いましょう。
describeメソッドにはaxis=1のオプションはありません。
その代わり、行ごとに集計したい場合は、「(データフレーム名).T」と行列を転置してからdescribeメソッドを適用すればOKです。
ただし、今回の場合は「性別」という数値以外の列が含まれていますので、上記した「データの抽出」で点数の列のみピックアップしてから計算する必要があります。
これ以外の統計量が出したいなど、もう少し細かい内容は以下の記事にも整理しています。
条件ごとの集計
今度は、セルの条件ごとに集計したい場合です。
今までの書き方を組み合わせれば、
1 2 |
df_score[df_score["性別"]=="男性"].sum() df_score[df_score["性別"]=="女性"].sum() |
・・・のような書き方でも計算できますが、男性は男性、女性は女性で計算するのは面倒です。
(2つならまだしも、これが10個20個になることもあるので・・・)
そんなときはgroupbyメソッドを使います。
Excelで言う「ピボットテーブル」に近いです。
(pivot_tableという関数もありますが、groupbyでもpivot_tableとほぼ同様の処理ができます。)
例えば、男女別に集計して、科目別の平均点を見たい場合は以下のようにします。
1 |
df_score.groupby("性別").mean() |
すると・・・
男女別の平均点がすぐに分かりました。
この書き方で、「性別ごとにグルーピングして、グループごとの平均値を求める」という処理になります。
groupbyでも、meanだけでなく、上記のデータフレームの集計で使えるmax、min、countなどの関数が使えます。
データの並び替え
データをソートする方法です。
まずは、算数の点数が低い順(昇順)に並び替えてみます。
1 |
df_score.sort_values("算数") |
算数の点数が昇順に並び変わっています。
このようにデフォルトでは昇順になりますが、点数データならば普通は高い順(降順)に並び替えます。
そんな時は引数にascending=Falseを指定します。
1 |
df_score.sort_values("算数",ascending=False) |
これで、算数の点数が高い順に並び替えることができました。
データフレームからCSVへの書き出し
最後に、いじったデータフレームをCSVに書き出す方法です。
これには、データフレーム名の後に.to_csv(“ファイル名”)をくっつけます。
例えば、先ほどの「算数の点数が高い順に並び替えたデータ」をCSVにしたければ、
1 |
df_score.sort_values("算数",ascending=False).to_csv("result.csv") |
を実行すれば、以下のファイルが出来上がります。
【result.csv】
これで、CSVに書き出すことができました。
Excelでうまく表示出来ない場合は、データの読み込み時と同様に、encoding=”shift_jis”など文字コードを指定すると読み込めるようになる場合があります。
まとめ
では最後に、今までの応用問題として以下の操作をしてみます。
CSVデータを読み込み、理科が70点未満の男性の中で、算数の点数が悪い順に並び替えたデータを新たにCSVに書き出す
この操作を手順化してみると、
- データ読み込み
- データの抽出(男性で、理科の点数が50点以下)
- データの並び替え(算数の点数でソート)
- データの書き出し
となります。
これらの操作を逐一やっていけば良い訳です。ということで・・・
1 2 |
df_score = pd.read_csv("成績データ.csv",index_col="名前") df_score[(df_score["性別"]=="男性") & (df_score["理科"]<70)].sort_values("算数").to_csv("集計結果.csv",encoding="shift_jis") |
これで完成です。
・・・しかし、これでも問題は無いのですが、このように処理を1行に全部詰め込むと非常に読みづらくなります。
こういう場合は以下のように、1つずつ操作をしていき、その結果を適宜変数に代入して行く方が分かりやすくなるので、おすすめです。
1 2 3 4 5 6 7 8 9 10 11 |
# ファイルの読み込み df_score = pd.read_csv("成績データ.csv",index_col="名前") # 理科の点数が70点未満の男性に絞り込む df_score = df_score[(df_score["性別"]=="男性") & (df_score["理科"]<70)] # 算数の点数が低い順にソート df_score = df_score.sort_values("算数") # 結果の書き出し df_score.to_csv("集計結果.csv",encoding="shift_jis") |
「#」で始めた行は「コメントアウト」と言い、プログラムと関係なしに自分の好きな説明を書いておけます。
このコメントアウトも活用すれば、自分にも他人にも見やすい、良い分析コードを書くこともできます。
ソースコードは短く書けば良いという訳では無いので、このあたりも留意しておきましょう。
以上、基本的なデータフレーム操作でした。
今回紹介したのはデータフレーム操作のうちのごくわずかで、これ以外にもpandasには山のように便利なメソッドが揃っています、
しかし、このページに記載したことがまずは基本となりますので、これらをきちんと押さえておく事からPythonでのデータ分析の道が始まるかと思います。