Python3でのパンダとJupyterNotebookを使用したデータ分析と視覚化

提供:Dev Guides
移動先:案内検索

序章

Python pandasパッケージは、データの操作と分析に使用され、ラベル付きデータまたはリレーショナルデータを直感的に操作できるように設計されています。

pandasパッケージはスプレッドシート機能を提供しますが、Pythonを使用しているため、従来のグラフィカルなスプレッドシートプログラムよりもはるかに高速で効率的です。

このチュートリアルでは、使用する大規模なデータセットの設定、pandasgroupby()および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変数に渡します。 ここでも、NameSexの列、および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を続行すると、次の表が表示されます。

ピボットテーブルを使用すると、既存のテーブルから新しいテーブルを作成して、そのデータをどのようにグループ化するかを決定できます。

データの視覚化

pandasmatplotlibなどの他のパッケージと一緒に使用することで、ノートブック内のデータを視覚化できます。

長年にわたる特定の名前の人気に関するデータを視覚化する予定です。 そのためには、インデックスを設定および並べ替えてデータを作り直し、特定の名前の人気の変化を確認できるようにする必要があります。

pandasパッケージを使用すると、階層的またはマルチレベルのインデックス作成を実行できます。これにより、任意の次元数のデータを保存および操作できます。

性別、名前、年の順にデータのインデックスを作成します。 また、インデックスを並べ替える必要があります。

all_names_index = all_names.set_index(['Sex','Name','Year']).sort_index()

ALT + ENTERと入力して実行し、次の行に進みます。次の行で、ノートブックに新しいインデックス付きDataFrameが表示されます。

all_names_index

コードを実行してALT + ENTERを続行すると、出力は次のようになります。

次に、名前の人気を時間の経過とともにプロットする関数を作成します。 関数name_plotを呼び出し、関数の実行時に呼び出すパラメーターとしてsexnameを渡します。

def name_plot(sex, name):

次に、作成したテーブルを保持するためにdataという変数を設定します。 また、インデックスの値で行を選択するために、pandas DataFramelocを使用します。 この場合、locは、sexnameの両方のデータを参照して、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を使用して単語の頻度をグラフ化する方法]のガイドに従ってください。 ]。