Python3でのパンダとJupyterNotebookを使用したデータ分析と視覚化
序章
Python pandas
パッケージは、データの操作と分析に使用され、ラベル付きデータまたはリレーショナルデータを直感的に操作できるように設計されています。
pandas
パッケージはスプレッドシート機能を提供しますが、Pythonを使用しているため、従来のグラフィカルなスプレッドシートプログラムよりもはるかに高速で効率的です。
このチュートリアルでは、使用する大規模なデータセットの設定、pandas
のgroupby()
およびpivot_table()
関数、そして最後にデータを視覚化する方法について説明します。
pandas
パッケージについてある程度理解するには、チュートリアル Python3でのpandasパッケージとそのデータ構造の概要を読むことができます。
前提条件
このガイドでは、ローカルデスクトップまたはリモートサーバーのいずれかでpandas
のデータを操作する方法について説明します。 大規模なデータセットの操作はメモリを大量に消費する可能性があるため、いずれの場合も、このガイドの計算の一部を実行するには、コンピュータに少なくとも2GBのメモリが必要です。
このチュートリアルでは、 JupyterNotebookを使用してデータを操作します。 まだお持ちでない場合は、チュートリアルに従って、Python3用のJupyterNotebookをインストールおよびセットアップする必要があります。
データの設定
このチュートリアルでは、 SocialSecurityWebサイトから8MBのzipファイルとして入手できる赤ちゃんの名前に関する米国の社会保障データを使用します。
ローカルマシンまたはサーバーの正しいディレクトリからPython3プログラミング環境をアクティブ化しましょう。
cd environments
. my_env/bin/activate
次に、プロジェクトの新しいディレクトリを作成しましょう。 names
と呼んで、次のディレクトリに移動できます。
mkdir names cd names
このディレクトリ内で、curl
コマンドを使用して、社会保障Webサイトからzipファイルをプルできます。
curl -O https://www.ssa.gov/oact/babynames/names.zip
ファイルがダウンロードされたら、使用するすべてのパッケージがインストールされていることを確認しましょう。
numpy
多次元配列をサポートmatplotlib
データを視覚化するpandas
データ分析用seaborn
は、matplotlib統計グラフィックスをより美しくします
パッケージがまだインストールされていない場合は、次のようにpip
を使用してインストールします。
pip install pandas pip install matplotlib pip install seaborn
numpy
パッケージも、まだインストールされていない場合はインストールされます。
これで、JupyterNotebookを起動できます。
jupyter notebook
Jupyter NotebookのWebインターフェイスにアクセスすると、そこにnames.zip
ファイルが表示されます。
新しいノートブックファイルを作成するには、右上のプルダウンメニューから New > Python3を選択します。
これにより、ノートブックが開きます。
使用するパッケージをインポートすることから始めましょう。 ノートブックの上部に、次のように書く必要があります。
import numpy as np import matplotlib.pyplot as pp import pandas as pd import seaborn
ALT + ENTER
と入力すると、このコードを実行して新しいコードブロックに移動できます。
また、PythonNotebookにグラフをインラインに保つように指示しましょう。
matplotlib inline
コードを実行して、ALT + ENTER
と入力して続行します。
ここから、zipアーカイブを解凍し、CSVデータセットをpandas
にロードしてから、pandas
DataFramesを連結します。
Zipアーカイブを解凍します
zipアーカイブを現在のディレクトリに解凍するには、zipfile
モジュールをインポートしてから、ファイル名(この場合はnames.zip
)を使用してZipFile
関数を呼び出します。 :
import zipfile zipfile.ZipFile('names.zip').extractall('.')
コードを実行して、ALT + ENTER
と入力して続行できます。
ここで、names
ディレクトリを振り返ると、CSV形式の名前データの.txt
ファイルがあります。 これらのファイルは、1881年から2015年までのファイルのデータの年数に対応します。 これらの各ファイルは、同様の命名規則に従います。 たとえば、2015年のファイルはyob2015.txt
と呼ばれ、1927年のファイルはyob1927.txt
と呼ばれます。
これらのファイルの1つの形式を確認するために、Pythonを使用してファイルを開き、上位5行を表示してみましょう。
open('yob2015.txt','r').readlines()[:5]
コードを実行し、ALT + ENTER
を続行します。
Output['Emma,F,20355\n', 'Olivia,F,19553\n', 'Sophia,F,17327\n', 'Ava,F,16286\n', 'Isabella,F,15504\n']
データのフォーマット方法は、最初に名前(Emma
またはOlivia
のように)、次に性別(F
のように女性の名前、M
のように)です。男性の名前)、そしてその年にその名前で生まれた赤ちゃんの数(2015年に生まれたEmmaという名前の赤ちゃんは20,355人でした)。
この情報を使用して、データをpandas
にロードできます。
CSVデータをpandas
にロードします
カンマ区切りの値データをpandas
にロードするには、pd.read_csv()
関数を使用して、テキストファイルの名前と決定した列名を渡します。 これを変数(この場合はnames2015
)に割り当てます。これは、2015年の出生ファイルのデータを使用しているためです。
names2015 = pd.read_csv('yob2015.txt', names = ['Name', 'Sex', 'Babies'])
ALT + ENTER
と入力してコードを実行し、続行します。
これがうまくいったことを確認するために、テーブルの上部を表示してみましょう。
names2015.head()
コードを実行してALT + ENTER
を続行すると、次のような出力が表示されます。
これで、テーブルには、名前、性別、および各名前で生まれた赤ちゃんの数の情報が列ごとに整理されています。
pandas
オブジェクトを連結します
pandas
オブジェクトを連結すると、names
ディレクトリ内のすべての個別のテキストファイルを操作できるようになります。
これらを連結するには、最初に、入力されていないリストデータ型に変数を割り当ててリストを初期化する必要があります。
all_years = []
それが済んだら、 for loop を使用して、1880年から2015年までのすべてのファイルを年ごとに反復処理します。 2015年の終わりに+1
を追加して、2015年がループに含まれるようにします。
all_years = [] for year in range(1880, 2015+1):
ループ内で、 string formatter を使用して各テキストファイルの値をリストに追加し、これらの各ファイルの異なる名前を処理します。 これらの値をyear
変数に渡します。 ここでも、Name
、Sex
の列、およびBabies
の数を指定します。
all_years = [] for year in range(1880, 2015+1): all_years.append(pd.read_csv('yob{}.txt'.format(year), names = ['Name', 'Sex', 'Babies']))
さらに、注文を維持するために、年ごとに列を作成します。 これは、ループの進行中に-1
のインデックスを使用してそれらを指すことにより、各反復後に実行できます。
all_years = [] for year in range(1880, 2015+1): all_years.append(pd.read_csv('yob{}.txt'.format(year), names = ['Name', 'Sex', 'Babies'])) all_years[-1]['Year'] = year
最後に、pd.concat()
関数を使用して、連結してpandas
オブジェクトに追加します。 この情報を格納するために変数all_names
を使用します。
all_years = [] for year in range(1880, 2015+1): all_years.append(pd.read_csv('yob{}.txt'.format(year), names = ['Name', 'Sex', 'Babies'])) all_years[-1]['Year'] = year all_names = pd.concat(all_years)
ALT + ENTER
を使用してループを実行し、結果のテーブルの末尾(最下部の行)を呼び出して出力を検査できます。
all_names.tail()
これでデータセットが完成し、pandas
で追加の作業を行う準備が整いました。
データのグループ化
pandas
を使用すると、.groupby()
機能を使用して列ごとにデータをグループ化できます。 完全なデータセットにall_names
変数を使用すると、groupby()
を使用してデータをさまざまなバケットに分割できます。
データセットを性別と年でグループ化しましょう。 これは次のように設定できます。
group_name = all_names.groupby(['Sex', 'Year'])
コードを実行して、ALT + ENTER
を続行できます。
この時点で、group_name
変数を呼び出すだけで、次の出力が得られます。
Output<pandas.core.groupby.DataFrameGroupBy object at 0x1187b82e8>
これは、それがDataFrameGroupBy
オブジェクトであることを示しています。 このオブジェクトには、データをグループ化する方法についての指示がありますが、値を表示する方法についての指示はありません。
値を表示するには、指示を与える必要があります。 たとえば、.size()
、.mean()
、および.sum()
を計算して、テーブルを返すことができます。
.size()
から始めましょう。
group_name.size()
コードを実行してALT + ENTER
を続行すると、出力は次のようになります。
OutputSex Year F 1880 942 1881 938 1882 1028 1883 1054 1884 1172 ...
このデータは見た目は良いですが、もっと読みやすくなる可能性があります。 .unstack
関数を追加することで、読みやすくすることができます。
group_name.size().unstack()
コードを実行してALT + ENTER
と入力し続けると、出力は次のようになります。
このデータからわかるのは、毎年女性と男性の名前がいくつあったかということです。 たとえば、1889年には、1,479人の女性の名前と1,111人の男性の名前がありました。 2015年には、18,993人の女性の名前と13,959人の男性の名前がありました。 これは、時間の経過とともに名前に大きな多様性があることを示しています。
生まれた赤ちゃんの総数を知りたい場合は、.sum()
関数を使用できます。 これを、以前に作成した単一のyob2015.txt
ファイルから設定されたnames2015
という小さなデータセットに適用してみましょう。
names2015.groupby(['Sex']).sum()
ALT + ENTER
と入力してコードを実行し、続行します。
これは、2015年に生まれた男性と女性の赤ちゃんの総数を示していますが、その年に少なくとも5回名前が使用された赤ちゃんのみがデータセットにカウントされます。
pandas
.groupby()
関数を使用すると、データを意味のあるグループにセグメント化できます。
ピボットテーブル
ピボットテーブルは、データを要約するのに役立ちます。 1つのテーブルに保存されているデータを自動的に並べ替え、カウント、合計、または平均化できます。 次に、それらのアクションの結果を、その要約されたデータの新しいテーブルに表示できます。
pandas
では、pivot_table()
関数を使用してピボットテーブルを作成します。
ピボットテーブルを作成するには、最初に操作するDataFrameを呼び出し、次に表示するデータとそれらのグループ化方法を呼び出します。
この例では、all_names
データを操作し、一方のディメンションで名前、もう一方のディメンションで年でグループ化された赤ちゃんのデータを表示します。
pd.pivot_table(all_names, 'Babies', 'Name', 'Year')
ALT + ENTER
と入力してコードを実行して続行すると、次の出力が表示されます。
これは多くの空の値を示しているため、NameとYearを、一方の場合は行として、もう一方の場合は列としてではなく、列として保持することをお勧めします。 これを行うには、データを角かっこで囲みます。
pd.pivot_table(all_names, 'Babies', ['Name', 'Year'])
ALT + ENTER
と入力してコードを実行して続行すると、このテーブルには、各名前の記録にある年のデータのみが表示されます。
OutputName Year Aaban 2007 5.0 2009 6.0 2010 9.0 2011 11.0 2012 11.0 2013 14.0 2014 16.0 2015 15.0 Aabha 2011 7.0 2012 5.0 2014 9.0 2015 7.0 Aabid 2003 5.0 Aabriella 2008 5.0 2014 5.0 2015 5.0
さらに、次のように、データをグループ化して、名前と性別を1つのディメンションとして、年をもう1つのディメンションとして持つことができます。
pd.pivot_table(all_names, 'Babies', ['Name', 'Sex'], 'Year')
コードを実行してALT + ENTER
を続行すると、次の表が表示されます。
ピボットテーブルを使用すると、既存のテーブルから新しいテーブルを作成して、そのデータをどのようにグループ化するかを決定できます。
データの視覚化
pandas
をmatplotlib
などの他のパッケージと一緒に使用することで、ノートブック内のデータを視覚化できます。
長年にわたる特定の名前の人気に関するデータを視覚化する予定です。 そのためには、インデックスを設定および並べ替えてデータを作り直し、特定の名前の人気の変化を確認できるようにする必要があります。
pandas
パッケージを使用すると、階層的またはマルチレベルのインデックス作成を実行できます。これにより、任意の次元数のデータを保存および操作できます。
性別、名前、年の順にデータのインデックスを作成します。 また、インデックスを並べ替える必要があります。
all_names_index = all_names.set_index(['Sex','Name','Year']).sort_index()
ALT + ENTER
と入力して実行し、次の行に進みます。次の行で、ノートブックに新しいインデックス付きDataFrameが表示されます。
all_names_index
コードを実行してALT + ENTER
を続行すると、出力は次のようになります。
次に、名前の人気を時間の経過とともにプロットする関数を作成します。 関数name_plot
を呼び出し、関数の実行時に呼び出すパラメーターとしてsex
とname
を渡します。
def name_plot(sex, name):
次に、作成したテーブルを保持するためにdata
という変数を設定します。 また、インデックスの値で行を選択するために、pandas
DataFrameloc
を使用します。 この場合、loc
は、sex
とname
の両方のデータを参照して、MultiIndexのフィールドの組み合わせに基づく必要があります。
この構造を関数に記述してみましょう。
def name_plot(sex, name): data = all_names_index.loc[sex, name]
最後に、pp
としてインポートしたmatplotlib.pyplot
を使用して値をプロットします。 次に、性別と名前のデータの値をインデックスに対してプロットします。これは、私たちの目的では年です。
def name_plot(sex, name): data = all_names_index.loc[sex, name] pp.plot(data.index, data.values)
ALT + ENTER
と入力して実行し、次のセルに移動します。 これで、選択した性別と名前で関数を呼び出すことができます。たとえば、F
は、指定された名前Danica
の女性の名前です。
name_plot('F', 'Danica')
ここでALT + ENTER
と入力すると、次の出力が表示されます。
使用しているシステムによっては、フォントの置換に関する警告が表示される場合がありますが、データは正しくプロットされます。
視覚化を見ると、女性の名前であるダニカの人気は1990年頃にわずかに上昇し、2010年の直前にピークに達したことがわかります。
作成した関数を使用して、複数の名前のデータをプロットできるため、さまざまな名前の経時的な傾向を確認できます。
プロットを少し大きくすることから始めましょう。
pp.figure(figsize = (18, 8))
次に、プロットしたいすべての名前のリストを作成しましょう。
pp.figure(figsize = (18, 8)) names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
これで、for
ループを使用してリストを反復処理し、各名前のデータをプロットできます。 まず、これらのジェンダーニュートラルな名前を女性の名前として試します。
pp.figure(figsize = (18, 8)) names = ['Sammy', 'Jesse', 'Drew', 'Jamie'] for name in names: name_plot('F', name)
このデータを理解しやすくするために、凡例を含めましょう。
pp.figure(figsize = (18, 8)) names = ['Sammy', 'Jesse', 'Drew', 'Jamie'] for name in names: name_plot('F', name) pp.legend(names)
ALT + ENTER
と入力してコードを実行し、続行すると、次の出力が表示されます。
それぞれの名前が女性の名前として徐々に人気を博している一方で、ジェイミーという名前は1980年頃に女性の名前として圧倒的に人気がありました。
同じ名前をプロットしてみましょうが、今回は男性の名前です。
pp.figure(figsize = (18, 8)) names = ['Sammy', 'Jesse', 'Drew', 'Jamie'] for name in names: name_plot('M', name) pp.legend(names)
ここでも、ALT + ENTER
と入力してコードを実行し、続行します。 グラフは次のようになります。
このデータは、名前全体でより人気があり、ジェシーが一般的に最も人気のある選択肢であり、1980年代と1990年代に特に人気があったことを示しています。
ここから、引き続き名前データを操作し、さまざまな名前とその人気についての視覚化を作成し、さまざまなデータを調べて視覚化する他のスクリプトを作成できます。
結論
このチュートリアルでは、データの設定から、groupby()
およびpivot_table()
によるデータのグループ化、MultiIndexによるデータのインデックス作成、 [の視覚化]まで、大規模なデータセットを操作する方法を紹介しました。 matplotlib
パッケージを使用したX203X]データ。
多くの組織や機関は、pandas
とデータの視覚化について引き続き学習するために使用できるデータセットを提供しています。 たとえば、米国政府はdata.govを通じてデータを提供しています。
matplotlib
でデータを視覚化する方法について詳しくは、matplotlibを使用してPython3でデータをプロットする方法とPython3[X205Xでmatplotlibを使用して単語の頻度をグラフ化する方法]のガイドに従ってください。 ]。