{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# [グループワーク] ファイル読み込み・データ加工\n",
"Pandasを使ったファイルの読み込み~データ加工までを行う課題にチャレンジしましょう。\n",
"\n",
"# 事前準備\n",
"本講義で使用するファイルをダウンロードしておきましょう。次のコードを実行してください。"
],
"metadata": {
"id": "0aW1Kiskmag1"
}
},
{
"cell_type": "code",
"source": [
"# gitからデータを取得する。\n",
"%cd /content/\n",
"!rm -rf python_intermediate_2022\n",
"!git clone https://github.com/tendo-sms/python_intermediate_2022\n",
"%cd /content/python_intermediate_2022/05_GW_pandas"
],
"metadata": {
"id": "Rul6_E1fY_PX"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"# グループワークその1 \n",
"## (Pandasを使ったファイルの読み込み~データ加工までを行う課題にチャレンジ)\n",
"\n",
"これまでに学んできた知識を参考に、とあるスペクトルデータが保存されているExcelファイルからデータを読み出し、データの整形や加工に取り組んでみましょう。\n",
"\n",
"Excelファイルのデータには実習用に細工を施しております。\n",
"\n",
"データの中身を調査しながら課題にチャレンジしてみましょう。\n",
"\n",
"- [pandasでExcelファイルの読む](#pandasでExcelファイルの読む)\n",
"- [各シートを結合させてひとつのデータフレームにする](#各シートを結合させてひとつのデータフレームにする)\n",
"- [単位換算する](#単位換算する)\n",
"- [欠測定値を補完する](#欠測定値を補完する)\n"
],
"metadata": {
"id": "J6b8g3scdDvK"
}
},
{
"cell_type": "markdown",
"source": [
"\n",
"## pandasでExcelファイルを読み込んでみよう\n",
"\n",
"**[目標1]**\n",
"\n",
"複数シートが存在するExcelデータを読み込み、中身を簡単に確認してみましょう。\n"
],
"metadata": {
"id": "2tfRwzXCZUBP"
}
},
{
"cell_type": "markdown",
"source": [
"### Excelデータを読み込もう!\n",
"\n",
"**[課題1-1]**\n",
"\n",
"サンプルにExcelデータ(sample.xlsx)を読み込み、「data1」シートを変数**df_data1**に、「data2」シートを変数**df_data2**に入れてみましょう。\n",
"\n",
"読み込んだら、次のコマンドで正しく読み込めているか確認してください。\n",
"\n",
"`print(\"df_data1のデータタイプ\", type(df_data1))`\n",
"\n",
"`print(\"df_data2のデータタイプ\", type(df_data2))`\n",
"\n",
"ヒント:read_excel、オプションsheet_name"
],
"metadata": {
"id": "viUukWZv5sZR"
}
},
{
"cell_type": "code",
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"# 方法1 シート名を指定して読み込む。\n",
"\"\"\"\n",
"この方法はシート名を事前に知っておく必要があります。\n",
"\"\"\"\n",
"df_data1 = pd.read_excel(\"sample.xlsx\", sheet_name=\"data1\")\n",
"df_data2 = pd.read_excel(\"sample.xlsx\", sheet_name=\"data2\")\n",
"print(\"df_data1のデータタイプ\", type(df_data1))\n",
"print(\"df_data2のデータタイプ\", type(df_data2))\n",
"\n",
"# 方法2 シート番号を指定して読み込む。\n",
"\"\"\"\n",
"シートの順番が統一されている必要があります。\n",
"\"\"\"\n",
"df_data1 = pd.read_excel(\"sample.xlsx\", sheet_name=0)\n",
"df_data2 = pd.read_excel(\"sample.xlsx\", sheet_name=1)\n",
"print(\"df_data1のデータタイプ\", type(df_data1))\n",
"print(\"df_data2のデータタイプ\", type(df_data2))\n",
"\n",
"# 方法3 全体を読み込んでから、シートごとに判断する。\n",
"df_data_all = pd.read_excel(\"sample.xlsx\", sheet_name=None)\n",
"df_data1 = df_data_all[\"data1\"]\n",
"df_data2 = df_data_all[\"data2\"]\n",
"print(\"df_data1のデータタイプ\", type(df_data1))\n",
"print(\"df_data2のデータタイプ\", type(df_data2))\n",
"\n",
"# 今回の実習ではどの方法でも構いませんが、できるだけ汎用性が高いコードを心がけましょう。\n",
"# 一部のケースだけしか考慮されていない方法では、あとで苦労することになります。"
],
"metadata": {
"id": "A6ODdKoO3h-C"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 各シートのデータの中身を簡単に確認してみましょう!\n",
"\n",
"**[課題1-2]**\n",
"\n",
"変数**df_data1**と**df_data2**について、以下の内容を表示してみましょう。\n",
"\n",
"- 最初の先頭5行を表示\n",
"- 行数、列数を表示\n",
"- 各列のデータタイプの表示\n",
"\n",
"ヒント:head、shape、dtypes"
],
"metadata": {
"id": "pCbrP0gS4H_m"
}
},
{
"cell_type": "code",
"source": [
"# data1について\n",
"print(\"data1のデータ\")\n",
"print(df_data1.head(5))\n",
"print(\"data1の行数\")\n",
"print(df_data1.shape)\n",
"print(\"data1のデータタイプ\")\n",
"print(df_data1.dtypes)\n",
"\n",
"# data2について\n",
"print(\"data2のデータ\")\n",
"print(df_data2.head(5))\n",
"print(\"data2の行数\")\n",
"print(df_data2.shape)\n",
"print(\"data2のデータタイプ\")\n",
"print(df_data2.dtypes)\n",
"\n",
"\n",
"#df_data2のIntensity [a.u]はobject型になっています。\n",
"#欠測値が\"-\"(ハイフン)が含まれているため数値型に変換できないためobject型として読み込まれています。\n",
"#このままだと数値として計算することができないだけでなく、図化することができません。"
],
"metadata": {
"id": "z1nwRgAM4U4y"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"\n",
"## データを数値型にして欠測値の削除/補完をしてみよう\n",
"\n",
"**[目標2]**\n",
"\n",
"**df_data2**の「Intensity [a.u]」列のデータ型をfloat64にして、欠測値を削除 or 補完をしてみましょう。"
],
"metadata": {
"id": "2EEEFvk3pXmE"
}
},
{
"cell_type": "markdown",
"source": [
"### 特定の列を数値型に変換しよう!\n",
"\n",
"**[課題2-1]**\n",
"\n",
"**df_data2**の「Intensity [a.u]」列を数値型に変換してみましょう。\n",
"\n",
"欠測値はnp.nanとして、数値はfloat型で定義してください。\n",
"\n",
"変換ができたら、次のコマンドで確認してください。\n",
"\n",
"`print(df_data2.head(5))`\n",
"\n",
"`print(df_data2.dtypes)`\n",
"\n",
"ヒント:loc、fancy、astype、to_numeric"
],
"metadata": {
"id": "qXVwmKem0Emt"
}
},
{
"cell_type": "code",
"source": [
"# 方法1 astypeを使って変換する。\n",
"\"\"\"\n",
"fancyで指定する場合は代入を繰り返すとワーニングが発生することがあります。\n",
"\n",
"df_data2[df_data2[\"Intensity [a.u]\"]==\"-\"][\"astype\"] = np.nan\n",
"df_data2[df_data2[\"Intensity [a.u]\"]!=\"-\"][\"astype\"] = df_data2[df_data2[\"Intensity [a.u]\"]!=\"-\"][\"Intensity [a.u]\"].astype(float)\n",
"\n",
"次のようなワーニングが発生する。\n",
"/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:10: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\"\"\"\n",
"df_data2.loc[df_data2[\"Intensity [a.u]\"]==\"-\", \"astype\"] = np.nan\n",
"df_data2.loc[df_data2[\"Intensity [a.u]\"]!=\"-\", \"astype\"] = df_data2[df_data2[\"Intensity [a.u]\"]!=\"-\"][\"Intensity [a.u]\"].astype(float)\n",
"print(df_data2.head(5))\n",
"print(df_data2.dtypes)\n",
"print(\"-\"*100)\n",
"\n",
"# 方法2 to_numericを使って変換する。\n",
"\"\"\"\n",
"to_numericのerrorsオプションは「数値に変換できない」場合の挙動を指定できます。\n",
"\n",
"raise:例外を表示し、エラーを返す。\n",
"coerce:NaNに変換する。\n",
"ignore:数値変換はせず、そのままの値にする。\n",
"\"\"\"\n",
"df_data2[\"to_numeric\"] = pd.to_numeric(df_data2[\"Intensity [a.u]\"], errors=\"coerce\")\n",
"print(df_data2.head(5))\n",
"print(df_data2.dtypes)\n",
"print(\"-\"*100)\n",
"\n",
"# 新たに「astype」列と「to_numeric」列を作成していますが、「Intensity [a.u]」を置き換えてください。\n",
"df_data2[\"Intensity [a.u]\"] = pd.to_numeric(df_data2[\"Intensity [a.u]\"], errors=\"coerce\")\n",
"df_data2 = df_data2[[\"Energy [keV]\", \"Intensity [a.u]\", \"scale\"]]\n",
"print(df_data2.head(5))\n",
"print(df_data2.dtypes)\n"
],
"metadata": {
"id": "U63zoPeoRxEH"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 欠測値の行を削除してみよう!\n",
"\n",
"**[課題2-2]**\n",
"\n",
"先ほど、**df_data2**の「Intensity [a.u]」列の\"-\"(ハイフン)をNaNに変換しました。\n",
"\n",
"NaNの場合は行を削除してみましょう。\n",
"\n",
"まずは**df_data2**を**df_data2_2**としてコピーしてください。\n",
"\n",
"`df_data2_2 = df_data2.copy()`\n",
"\n",
"削除ができたら、次のコマンドで確認してください。\n",
"\n",
"`print(df_data2_2.head(5))`\n",
"\n",
"`print(df_data2_2.shape)`\n",
"\n",
"ヒント:dropna"
],
"metadata": {
"id": "8HiN3QwkmdHO"
}
},
{
"cell_type": "code",
"source": [
"# データフレームをコピー\n",
"df_data2_2 = df_data2.copy()\n",
"\n",
"# Intensity [a.u]に欠測値がある行(レコード)を削除する。\n",
"df_data2_2.dropna(subset=[\"Intensity [a.u]\"], inplace=True)\n",
"\n",
"print(df_data2_2.head(5))\n",
"print(df_data2_2.shape)"
],
"metadata": {
"id": "ORkArR8EEPlc"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"### 欠測値を補完してみよう!\n",
"\n",
"**[課題2-3]**\n",
"\n",
"まずは**df_data2**を**df_data2_3**としてコピーしてください。\n",
"\n",
"`df_data2_3 = df_data2.copy()`\n",
"\n",
"補完した結果は、「fillna」と「interpolate」列を追加して保存してください。\n",
"\n",
"結果は次の命令文で確認してください。\n",
"\n",
"`print(df_data2_3.iloc[60:70])`\n",
"\n",
"ヒント:fillna、interpolate"
],
"metadata": {
"id": "-DriQ3Oqq5Fv"
}
},
{
"cell_type": "code",
"source": [
"# データフレームをコピー\n",
"df_data2_3 = df_data2.copy()\n",
"\n",
"# ffillで欠測値を埋める\n",
"df_data2_3[\"fillna\"] = df_data2_3[\"Intensity [a.u]\"].fillna(method=\"ffill\")\n",
"\n",
"# ffillで欠測値を埋める\n",
"df_data2_3[\"interpolate\"] = df_data2_3[\"Intensity [a.u]\"].interpolate(limit_direction=\"both\")\n",
"\n",
"# 結果の表示\n",
"print(df_data2_3.iloc[60:70])"
],
"metadata": {
"id": "Dr5gXnCdrUTe"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"\n",
"## 単位換算をしてみよう\n",
"\n",
"**[目標3]**\n",
"\n",
"欠測データを削除した**df_data2_2**を使って、「Intensity [a.u]」列の単位を換算しましょう。\n",
"\n"
],
"metadata": {
"id": "tue6_ow4XPo7"
}
},
{
"cell_type": "markdown",
"source": [
"### 特定の列を参考にしながら単位換算してみよう!\n",
"\n",
"**[課題3-1]**\n",
"\n",
"**df_data2_2**の「scale」列には、「Intensity [a.u]」を何倍すればよいか数値が入っています。\n",
"\n",
"こちらを参照して計算した結果を「Intensity [a.u]」列に置き換えてみましょう。\n",
"\n",
"変換ができたら、次のコマンドで確認してください。\n",
"\n",
"`print(df_data2_2)`\n",
"\n",
"ヒント:fancy、astype"
],
"metadata": {
"id": "SNL_kz0yYilf"
}
},
{
"cell_type": "code",
"source": [
"# ffillで欠測値を埋める\n",
"df_data2_2[\"Intensity [a.u]\"] = df_data2_2[\"Intensity [a.u]\"] * df_data2_2[\"scale\"].astype(float)\n",
"\n",
"# 結果の表示\n",
"print(df_data2_2)"
],
"metadata": {
"id": "AyADq29bvUiW"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"\n",
"## 結果を可視化してみよう\n",
"\n",
"**[目標4]**\n",
"\n",
"結果をpandasから簡単に可視化してみましょう。\n"
],
"metadata": {
"id": "0uJSj3fKfp_R"
}
},
{
"cell_type": "markdown",
"source": [
"### pandasから可視化してみよう!\n",
"\n",
"**[課題4-1]**\n",
"\n",
"**df_data2_2**を可視化してみましょう。\n",
"\n",
"X軸には「Energy [keV]」、Y軸には「Intensity [a.u]」を指定して折れ線グラフを描いてみよう。\n",
"\n",
"ヒント:df.plot\n",
"\n"
],
"metadata": {
"id": "DwWj9itDgBtF"
}
},
{
"cell_type": "code",
"source": [
"# X軸に「Energy [keV]」、Y軸は「Intensity [a.u]」を指定する。\n",
"df_data2_2.plot(figsize=(12, 10), x=\"Energy [keV]\", y=\"Intensity [a.u]\")"
],
"metadata": {
"id": "0RKl74X_fo9i"
},
"execution_count": null,
"outputs": []
}
]
}