はじめに#
Pandasは、Pythonでデータを扱う際によく用いられるライブラリであり、データ操作に特化しています。データ分析や機械学習プロジェクトにおけるデータ整理、加工、分析の基礎を築く上で非常に便利です。
以下に、Pandasライブラリの主要なデータ操作機能とその実用的な活用方法を説明します。
1. データの読み込みと確認#
- CSVファイルの読み込み:
pd.read_csv()メソッドを使用して、CSVファイルをデータフレーム(df)として読み込むことができます。これにより、外部の表形式データをPythonで扱えるようになります。 - データフレームの内容確認:
df.head(n): データフレームの先頭からn行を表示します。通常、データフレーム全体を見ることはないため、データの概要を素早く把握するのに役立ちます。df.tail(n): データフレームの末尾からn行を表示します。データが時系列順に並んでいる場合など、最新のデータを確認する際に便利です。
2. データの前処理(整形・クリーニング)#
データ分析において、生データはしばしば不要な情報や不備を含んでいます。これらを整形・クリーニングすることで、データの品質を高め、分析に適した形に整えます。
- 不要な行・列の削除(必要な部分の抽出):
- 特定の列を抽出することで、不要な列を実質的に削除できます。これは、データフレームの
df[カラム名のリスト]の形式で実現できます。例えば、単位情報や重複した情報を含むカラムなどを削除する際に用います。 - 特定の行を抽出することで、不要な行を実質的に削除できます。例えば、先頭行が不要なラベル情報である場合、
df[1:]のように指定して2行目以降のデータを抽出します。
- 特定の列を抽出することで、不要な列を実質的に削除できます。これは、データフレームの
- カラム名の変更:
df.columns = [新しいカラム名のリスト]を使用すると、データフレームの全てのカラム名を一度に変更できます。例えば、カラム名に含まれる単位などの不要な部分を一括で削除し、短く分かりやすい名前に変更する際に有効です。df.rename(columns={'変更前': '変更後'})メソッドを使用すると、特定のカラム名のみをピンポイントで変更できます。これは、多くのカラムがある中で一部だけ変更したい場合に便利です。ただし、df自体の中身は変わらないため、変更を永続化するには再度代入 (df = df.rename(...)) が必要です。
- 欠損値の処理:
- 欠損値の確認:
df.isnull()を使用すると、データフレーム内の各要素が欠損値(NaN)であるかどうかがTrue/Falseで判定されます。さらに、.sum()を組み合わせることで、各カラムにいくつ欠損値があるかを確認できます。これは、データ品質の問題を特定する上で重要です。 - 欠損値の補完:
df.fillna(値)メソッドは、データフレーム内の欠損値を指定した値で埋めます。例えば、欠損値を0で埋めることができます。実際には、データの性質に応じて中央値や平均値といった統計量で補完することが多いです。 - 欠損値の削除:
df.dropna(axis=値)メソッドは、欠損値を含む行または列を削除します。axis=1を指定すると列方向に、axis=0を指定すると行方向に削除されます。データ分析において、特にデータ数が少ないカラムや、その列全体が欠損値である場合に、その列を削除することでノイズを減らすことができます。
- 欠損値の確認:
- 重複の除去:
df.drop_duplicates(subset='カラム名')メソッドを使用すると、指定したカラム(subset)において重複する行を削除し、ユニークな行のみを残すことができます。subsetを指定しない場合、全てのカラムが一致する行が削除されます。 - データ型の確認:
df.dtypesを使用すると、データフレームの各カラムのデータ型を確認できます。これにより、データが意図した型で格納されているか、前処理が必要か(例: 文字列型の日付を日付型に変換するなど)を判断できます。 - ダミー変数への変換:
pd.get_dummies(df, columns=['カラム名'])メソッドは、カテゴリカルなデータを機械学習モデルで扱える数値データ(0または1)に変換するダミー変数化を行います。例えば、「国籍」のようなカテゴリカルな列を、「国籍_日本」「国籍_アメリカ」といった0/1の列に変換します。
3. データの抽出と選択#
データフレームから特定の条件を満たすデータや、特定の範囲のデータを柔軟に選択・抽出する機能です。
- 任意の要素の取得 (iloc, loc):
df.iloc[行インデックス, 列インデックス]は、インデックス番号(0から始まる位置)で指定して要素を抽出します。df.loc[行ラベル, 列ラベル]は、**行や列のラベル名(カラム名)**で指定して要素を抽出します。- これらは、データフレーム内の特定の部分をピンポイントで取得したい場合に非常に強力なツールです。
- 条件抽出:
- 特定の条件を満たす行を抽出するには、データフレームに対して直接条件式(例:
df[df['カラム名'] == '値'])を適用する方法が一般的です。複数の条件を組み合わせる場合は&(and) や|(or) で連結し、各条件を括弧で囲みます。 df.query('カラム名 == "値"')メソッドは、文字列形式で条件式を記述することで抽出を行います。df['カラム名'].isin(['値1', '値2'])メソッドは、指定した値のリストに含まれる要素を持つ行を抽出する際に便利です。 これらは、特定の条件(例: 「アメリカ国籍の20歳以上30歳未満の人物」など)に合致するデータを絞り込みたい場合に活用されます。
- 特定の条件を満たす行を抽出するには、データフレームに対して直接条件式(例:
4. データの集計と分析#
データから意味のある情報を導き出すための集計や統計分析を行う機能です。
- ユニークな値と出現回数の確認:
df['カラム名'].unique()メソッドは、指定したカラムに含まれるユニークな(重複しない)値のリストを取得します。df['カラム名'].value_counts()メソッドは、指定したカラムのユニークな値とその出現回数を一覧で表示します。これは、カテゴリカルデータの分布を理解する上で非常に役立ちます。
- グループごとの集計:
df.groupby('グループ化したいカラム名').mean()のようにgroupby()メソッドを使用すると、指定したカラムのカテゴリごとにデータをグループ化し、それぞれのグループで平均値(mean())などの統計量を算出できます。これにより、カテゴリ間の比較分析が容易になります。 - 統計量の確認:
df.mean(),df.median(),df.std(),df.max(),df.min()などを使用すると、データフレームの各カラムの平均値、中央値、標準偏差、最大値、最小値といった基本的な統計量を個別に算出できます。df.describe()メソッドは、これらの主要な統計量を一括で表形式で出力します。データの全体的な特性を素早く把握する際に非常に便利です。
- データの並び替え:
df.sort_values(by='カラム名', ascending=False)メソッドは、指定したカラムの値に基づいてデータフレームの行を並び替えます。ascending=Falseを設定すると降順(高い順)に、True(デフォルト)だと昇順(低い順)に並び替えることができます。 - 相関係数の算出:
df.corr()メソッドは、データフレーム内の数値型カラム間の相関係数を算出します。相関係数は、二つの値がどれだけ関係性があるかを示す指標で、正の相関(一方が増えれば他方も増える)は1に近く、負の相関(一方が増えれば他方が減る)は-1に近く、無相関は0に近くなります。これにより、変数間の関係性を数値で把握できます。
5. データの可視化と出力#
分析結果を視覚的に表現し、また加工したデータを再利用可能な形式で保存します。
- グラフ表示(可視化): Pandasのデータフレームは、
matplotlibライブラリと連携して直接グラフを描画する機能を持っています。例えば、df.plot(x='横軸カラム名', y=['縦軸カラム名1', '縦軸カラム名2'], kind='line', legend=False)のように指定することで、折れ線グラフなどを表示できます。データの特徴やトレンドを直感的に理解するために不可欠な機能です。ただし、日本語フォントの設定を行わないと文字化けすることがあります。 - データ出力:
df.to_csv('ファイル名.csv', index=False)メソッドは、加工済みのデータフレームをCSVファイルとして出力します。index=Falseを指定すると、データフレームのインデックス(左側の数値)は出力されません。これにより、クリーンアップまたは分析されたデータを他のツールやプロジェクトで再利用できます。
これらの機能を活用することで、データの読み込みから、前処理、分析、可視化、出力までの一連のデータ操作を効率的に行うことができます。
YouTubeチャンネル「いまにゅのプログラミング塾」の動画「【Pandas徹底講座】この動画1本でデータ操作に特化したPythonライブラリPandasの基礎をマスター!」で出題された20問のハンズオンについて、それぞれの概要と解説を以下にまとめます。この講座は、データ整理、加工、分析の基礎を固める上で非常に実用的な内容となっています。
Pandasハンズオン 20問 解説#
1. データの読み込み#
- 概要:
weather.csvファイルを読み込み、dfというデータフレームとして定義する。 - 解説: Pandasライブラリを
pdとしてインポートした後、pd.read_csv()メソッドを使用してCSVファイルを読み込みます。ファイル名を作業ディレクトリ内に指定するだけで読み込みが可能です。
import pandas as pd
df = pd.read_csv('weather.csv')
print(df)
2. データの中身確認#
- 概要: 読み込んだデータフレーム
dfの先頭3行と末尾10行を表示する。 - 解説: データフレーム全体を見ることは稀であるため、データの概要を把握する際に使います。
df.head(n): データフレームの先頭からn行を表示します(n=3)。df.tail(n): データフレームの末尾からn行を表示します(n=10)。
import pandas as pd
df = pd.read_csv('weather.csv')
print(df.head(3))
print(df.tail(10))
3. 不要な列・行の削除#
- 概要: データフレームから不要な先頭行(ラベル情報など)と、特定の不要な列(例:
平均気温.1、平均気温.2のように「.数字」が付く列)を削除し、dfとして再定義する。 - 解説: 一般的な
dropメソッドではなく、必要な部分のみを抽出するアプローチが推奨されています。- 列の抽出: 必要なカラム名のみをリストで指定し、
df[カラム名のリスト]の形式で抽出します。 - 行の抽出: 先頭行が不要な場合、
df[1:]のようにスライス表記を用いて2行目以降のデータを抽出します。
- 列の抽出: 必要なカラム名のみをリストで指定し、
# ラベル情報を抽出
import pandas as pd
df = pd.read_csv('weather.csv')
print(df.columns)
# 必要なラベルを抽出して表示させる
df = df[[
'年月日',
'平均気温(℃)',
'最高気温(℃)',
'最低気温(℃)',
'降水量の合計(mm)',
'最深積雪(cm)',
'平均雲量(10分比)',
'平均蒸気圧(hPa)',
'平均風速(m/s)',
'日照時間(時間)',
]]
print(df)
# 1行目から取得する場合
df = df[[
'年月日',
'平均気温(℃)',
'最高気温(℃)',
'最低気温(℃)',
'降水量の合計(mm)',
'最深積雪(cm)',
'平均雲量(10分比)',
'平均蒸気圧(hPa)',
'平均風速(m/s)',
'日照時間(時間)'
]][1:]
print(df)
4. データの形・サイズ、列名・行名、データ型の確認#
- 概要: 各列のデータ型、データフレームのサイズ(行数・列数)、列名(カラム名)、行名(インデックス)を取得する。
- 解説:
- データ型:
df.dtypesを使用し、各カラムのデータ型(数値型、オブジェクト型など)を確認します。 - サイズ:
df.shapeを使用し、データフレームの行数と列数を(行数, 列数)のタプル形式で取得します。 - 列名:
df.columnsを使用し、データフレームのカラム名リストを取得します。 - 行名(インデックス):
df.indexを使用し、行のインデックス情報を取得します。現在のインデックスが数値であれば、その範囲と刻みが表示されます。
- データ型:
print(df.dtypes)
print(df.shape)
print(df.columns)
print(df.index)
5. 任意の要素の取得#
- 概要:
dfの5行目から10行目まで、かつ3列目から6列目まで(最高気温から最深積雪まで)の要素を取得する。 - 解説: 特定の範囲のデータにアクセスするために、主に以下の2つの方法があります。
df.iloc[行インデックス, 列インデックス]: インデックス番号(0から始まる位置)で要素を抽出します。例えば、5行目から10行目(インデックス4から9)は4:10、3列目から6列目(インデックス2から5)は2:6と指定します。df.loc[行ラベル, 列ラベル]: **行ラベル名や列ラベル名(カラム名)**で要素を抽出します。行は5:10のように指定し、列は'最高気温':'最深積雪'のように範囲で指定します。locの行の範囲指定は終端を含みますが、ilocは含みません。
import pandas as pd
df = pd.read_csv('weather.csv')
print(df.iloc[4:10, 2:6])
print(df.loc[5:10,'最高気温(℃)':'最深積雪(cm)'])
6. 条件抽出#
- 概要:
people.csvをdf_peopleとして読み込み、以下の条件を満たすデータを抽出する。Nationalityが「America」であるもの。Ageが20以上30未満であるもの。
- 解説:
- 直接的な条件式:
df_people[df_people['Nationality'] == 'America']のように、データフレームに対して直接条件式を適用する方法がよく使われます。複数の条件を組み合わせる場合は、各条件を括弧で囲み、&(AND)や|(OR)で連結します(例:(df['Age'] >= 20) & (df['Age'] < 30))。 df.query()メソッド:df_people.query('Nationality == "America"')のように、文字列形式で条件式を記述して抽出することもできます。df['カラム名'].isin([])メソッド: 指定した値のリストに含まれる要素を持つ行を抽出する際に便利です(例:df_people['Nationality'].isin(['America']))。
- 直接的な条件式:
import pandas as pd
df_people = pd.read_csv('people.csv')
# n条件に合致したものがTrueとなり、Trueのみ表示させる
print(df_people[df_people['nationality'] == 'America'])
print(df_people[(df_people['age'] >= 20) & (df_people['age'] < 30)])
# こちらはクエリを利用した方法
print(df_people.query('nationality == "America"'))
# isinを利用した方法
print(df_people[df_people['nationality'].isin(['America'])])
7. ユニークな値の抽出#
- 概要:
df_peopleの各カラムについて、ユニークな(固有の)値を抽出する。 - 解説:
df['カラム名'].unique()メソッドを使用します。このメソッドはシリーズ(1次元データ)にしか適用できないため、データフレーム全体に直接適用するとエラーになることに注意が必要です。
import pandas as pd
df_people = pd.read_csv('people.csv')
print(df_people['nationality'].unique())
print(df_people['name'].unique())
print(df_people['age'].unique())
8. 重複除去#
- 概要:
df_peopleのNationality列において、重複する値を持つ行を削除し、重複がないデータフレームを取得する。 - 解説:
df.drop_duplicates(subset='カラム名')メソッドを使用します。subset引数を指定しない場合、すべてのカラムの値が一致する行が重複とみなされます。subset='Nationality'のように特定のカラム名を指定すると、そのカラムの値が重複する場合に該当する行を削除します。
import pandas as pd
df_people = pd.read_csv('people.csv')
print(df_people.drop_duplicates(subset='nationality'))
9. カラム名変更#
- 概要:
dfの各カラム名から、単位部分(例:(℃)、(mm))を削除する。 - 解説: カラム名を変更する方法はいくつかあります。
- 一括変更:
df.columns = [新しいカラム名のリスト]を使用し、すべてのカラム名を新しいリストで上書きします。これはカラム数が少ない場合に手動でリストを作成するのに便利です。 df.rename()メソッド:df.rename(columns={'変更前':'変更後'})を使用すると、特定のカラム名のみをピンポイントで変更できます。df.rename()はデフォルトではデータフレーム自体を直接変更しないため、変更を永続化するにはdf = df.rename(...)のように再代入が必要です。
- 一括変更:
import pandas as pd
df = pd.read_csv('weather.csv')
df.columns = [
'年月日',
'平均気温(℃)',
'最高気温(℃)',
'最低気温(℃)',
'降水量の合計(mm)',
'最深積雪(cm)',
'平均雲量(10分比)',
'平均蒸気圧(hPa)',
'平均風速(m/s)',
'日照時間(時間)'
]
df.rename(columns={
'平均気温':'平均'
})
10. 並び替え#
- 概要:
dfを最高気温が高い順(降順)に並び替える。 - 解説:
df.sort_values(by='カラム名', ascending=False)メソッドを使用します。by引数で並び替えの基準となるカラムを指定します。ascending=Falseを指定すると降順(高い順)に並び替えます。True(デフォルト)だと昇順(低い順)になります。
import pandas as pd
df = pd.read_csv('weather.csv')
print(df.sort_values('最高気温(℃)'))
print(df.sort_values('最高気温(℃)',ascending=False))
11. ダミー変数への処理#
- 概要:
df_peopleのNationalityカラムをダミー変数に変換する。 - 解説: カテゴリカルなデータを0または1で表現するダミー変数化には
pd.get_dummies()メソッドを使用します。pd.get_dummies(df, columns=['カラム名'])のように、変換したいデータフレームとカラム名を指定することで、指定したカラムのみをダミー変数化し、元のデータフレームに結合された形で取得できます。
import pandas as pd
df_people = pd.read_csv('people.csv')
df_people_dummy = pd.get_dummies(df_people, columns=['nationality'])
print(df_people_dummy)
12. 欠損値の確認#
- 概要:
df内の欠損値(値が入っていない要素)を確認する。 - 解説:
df.isnull()メソッドを使用します。これは、各要素が欠損値であればTrue、そうでなければFalseとなるブール型のデータフレームを返します。さらに、.sum()を組み合わせることで、各カラムの欠損値の合計数を簡単に確認できます(例:df.isnull().sum())。
import pandas as pd
df = pd.read_csv('weather.csv')
print(df.isnull().sum())
13. 欠損値の補完#
- 概要:
dfの欠損値をすべて0で補完(埋める)する。 - 解説:
df.fillna(値)メソッドを使用します。このメソッドの引数に0を指定することで、すべての欠損値が0で埋められます。実用上は、中央値や平均値などの統計量で補完することが多いです。
import pandas as pd
df = pd.read_csv('weather.csv')
df = df.fillna(0)
print(df.isnull().sum())
14. 欠損値の削除#
- 概要:
dfの欠損値を含む列を削除する。 - 解説:
df.dropna(axis=値)メソッドを使用します。axis=1: 列方向(カラム全体)に欠損値が存在する場合、その列を削除します。axis=0(デフォルト): 行方向(行全体)に欠損値が存在する場合、その行を削除します。- 今回のケースでは、一部の列がほとんど(またはすべて)欠損値であったため、行を削除するとほとんどのデータが失われるため、列方向の削除が適切でした。
df = df.dropna(...)のように再代入しないと、データフレーム自体は変更されません。
import pandas as pd
df = pd.read_csv('weather.csv')
df = df.dropna(axis=1)
print(df)
15. ユニークな値と出現回数#
- 概要:
iris.csvをdf_irisとして読み込み、Classカラムのユニークな値とそれぞれの出現回数を確認する。 - 解説:
df['カラム名'].value_counts()メソッドを使用します。これはシリーズに適用され、ユニークな値とその出現回数を高い順に表示します。
import pandas as pd
df_iris = pd.read_csv('iris.csv')
print(df_iris['Class'].value_counts())
16. グループごとの集計#
- 概要:
df_irisの各Class(Iris-setosa、Iris-versicolor、Iris-virginica)におけるSepal Length、Sepal Width、Petal Length、Petal Widthの平均値を求める。 - 解説:
df.groupby('グループ化したいカラム名').mean()のように、groupby()メソッドと集計メソッドを組み合わせます。groupby()で指定したカラム(例:Class)のカテゴリごとにデータをグループ化し、そのグループに対して平均値(mean())などの統計量を算出できます。mean()以外にもstd()(標準偏差)などが適用可能です。
import pandas as pd
df_iris = pd.read_csv('iris.csv')
print(df_iris.groupby('Class').mean())
17. 統計量の確認#
- 概要:
df_irisの各カラムについて、平均値、中央値、標準偏差、最大値、最小値を算出する。 - 解説:
- 個別の統計量:
df.mean()、df.median()、df.std()、df.max()、df.min()など、各統計量に対応するメソッドを直接呼び出すことができます。 - 一括統計量:
df.describe()メソッドは、これらの主要な統計量(カウント、平均、標準偏差、最小値、25パーセンタイル、中央値、75パーセンタイル、最大値)をまとめて表形式で出力し、データの全体像を素早く把握するのに非常に便利です。
- 個別の統計量:
import pandas as pd
df_iris = pd.read_csv('iris.csv')
# df_irisのClass列は文字列なので、数値計算の対象外にする
print(df_iris.drop(columns=['Class']).mean())
print(df_iris.drop(columns=['Class']).median())
print(df_iris.drop(columns=['Class']).std())
print(df_iris.drop(columns=['Class']).max())
print(df_iris.drop(columns=['Class']).min())
print(df_iris.describe())
18. 折れ線グラフの表示#
- 概要:
dfの最初の50日間のデータにおける平均気温、最高気温、最低気温を折れ線グラフで可視化する。横軸は年月とし、判例は表示しない。 - 解説: Pandasのデータフレームは
matplotlibと連携してグラフを描画できます。matplotlib.pyplotをpltとしてインポートします。- データの最初の50行を抽出し(例:
df[:50])、そのデータフレームに対してdf.plot(x='横軸カラム名', y=['縦軸カラム名1', '縦軸カラム名2'], kind='line', legend=False)メソッドを使用します。 kind='line'で折れ線グラフを指定し、legend=Falseで判例を非表示にします。日本語の文字化けが発生する可能性があるため、その場合はmatplotlibの日本語フォント設定が必要です。
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('weather.csv')
df = df[1:51] # 1行目から50行目まで
# 日本語の文字化け対策(環境に合わせてフォントを指定)
# plt.rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro']
df.plot(x='年月日', y=['平均気温(℃)', '最高気温(℃)', '最低気温(℃)'], kind='line', legend=False)
plt.show()
19. 相関係数の算出#
- 概要:
dfの平均気温、降水量の合計、日照時間の3項目における相関係数を算出する。 - 解説:
df.corr()メソッドを使用します。- 相関係数は、2つの変数間の関係性の強さを示す指標で、-1から1の間の値を取ります。
- 1に近いほど強い正の相関(一方が増えれば他方も増える)、-1に近いほど強い負の相関(一方が増えれば他方が減る)、0に近いほど相関がないことを示します。
- 特定の列の相関を見る場合は、それらの列を抽出したデータフレームに対して
corr()を適用します。データフレーム全体に適用すると、すべての数値型カラム間の相関係数を計算します。
import pandas as pd
df = pd.read_csv('weather.csv')
df = df[1:]
# データ型を数値に変換
df['平均気温(℃)'] = pd.to_numeric(df['平均気温(℃)'], errors='coerce')
df['降水量の合計(mm)'] = pd.to_numeric(df['降水量の合計(mm)'], errors='coerce')
df['日照時間(時間)'] = pd.to_numeric(df['日照時間(時間)'], errors='coerce')
print(df[['平均気温(℃)', '降水量の合計(mm)', '日照時間(時間)']].corr())
20. データの出力#
- 概要: 欠損値を
0で補完したdfをexport.csvというファイル名でCSVファイルとして出力する。この際、データフレームのインデックスは出力しない。 - 解説:
df.to_csv('ファイル名.csv', index=False)メソッドを使用します。- 第一引数に出力するファイル名を指定します。
index=Falseを指定することで、データフレームのインデックス番号がCSVファイルに出力されないようにします。
import pandas as pd
df = pd.read_csv('weather.csv')
df = df.fillna(0)
df.to_csv('export.csv', index=False)