# gitからデータを取得する。
%cd /content/
!rm -rf python_intermediate_2022
!git clone https://github.com/tendo-sms/python_intermediate_2022
%cd /content/python_intermediate_2022/05_GW_pandas
[課題1-1]
サンプルにExcelデータ(sample.xlsx)を読み込み、「data1」シートを変数df_data1に、「data2」シートを変数df_data2に入れてみましょう。
読み込んだら、次のコマンドで正しく読み込めているか確認してください。
print("df_data1のデータタイプ", type(df_data1))
print("df_data2のデータタイプ", type(df_data2))
ヒント:read_excel、オプションsheet_name
import pandas as pd
import numpy as np
# 方法1 シート名を指定して読み込む。
"""
この方法はシート名を事前に知っておく必要があります。
"""
df_data1 = pd.read_excel("sample.xlsx", sheet_name="data1")
df_data2 = pd.read_excel("sample.xlsx", sheet_name="data2")
print("df_data1のデータタイプ", type(df_data1))
print("df_data2のデータタイプ", type(df_data2))
# 方法2 シート番号を指定して読み込む。
"""
シートの順番が統一されている必要があります。
"""
df_data1 = pd.read_excel("sample.xlsx", sheet_name=0)
df_data2 = pd.read_excel("sample.xlsx", sheet_name=1)
print("df_data1のデータタイプ", type(df_data1))
print("df_data2のデータタイプ", type(df_data2))
# 方法3 全体を読み込んでから、シートごとに判断する。
df_data_all = pd.read_excel("sample.xlsx", sheet_name=None)
df_data1 = df_data_all["data1"]
df_data2 = df_data_all["data2"]
print("df_data1のデータタイプ", type(df_data1))
print("df_data2のデータタイプ", type(df_data2))
# 今回の実習ではどの方法でも構いませんが、できるだけ汎用性が高いコードを心がけましょう。
# 一部のケースだけしか考慮されていない方法では、あとで苦労することになります。
[課題1-2]
変数df_data1とdf_data2について、以下の内容を表示してみましょう。
ヒント:head、shape、dtypes
# data1について
print("data1のデータ")
print(df_data1.head(5))
print("data1の行数")
print(df_data1.shape)
print("data1のデータタイプ")
print(df_data1.dtypes)
# data2について
print("data2のデータ")
print(df_data2.head(5))
print("data2の行数")
print(df_data2.shape)
print("data2のデータタイプ")
print(df_data2.dtypes)
#df_data2のIntensity [a.u]はobject型になっています。
#欠測値が"-"(ハイフン)が含まれているため数値型に変換できないためobject型として読み込まれています。
#このままだと数値として計算することができないだけでなく、図化することができません。
[課題2-1]
df_data2の「Intensity [a.u]」列を数値型に変換してみましょう。
欠測値はnp.nanとして、数値はfloat型で定義してください。
変換ができたら、次のコマンドで確認してください。
print(df_data2.head(5))
print(df_data2.dtypes)
ヒント:loc、fancy、astype、to_numeric
# 方法1 astypeを使って変換する。
"""
fancyで指定する場合は代入を繰り返すとワーニングが発生することがあります。
df_data2[df_data2["Intensity [a.u]"]=="-"]["astype"] = np.nan
df_data2[df_data2["Intensity [a.u]"]!="-"]["astype"] = df_data2[df_data2["Intensity [a.u]"]!="-"]["Intensity [a.u]"].astype(float)
次のようなワーニングが発生する。
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:10: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
"""
df_data2.loc[df_data2["Intensity [a.u]"]=="-", "astype"] = np.nan
df_data2.loc[df_data2["Intensity [a.u]"]!="-", "astype"] = df_data2[df_data2["Intensity [a.u]"]!="-"]["Intensity [a.u]"].astype(float)
print(df_data2.head(5))
print(df_data2.dtypes)
print("-"*100)
# 方法2 to_numericを使って変換する。
"""
to_numericのerrorsオプションは「数値に変換できない」場合の挙動を指定できます。
raise:例外を表示し、エラーを返す。
coerce:NaNに変換する。
ignore:数値変換はせず、そのままの値にする。
"""
df_data2["to_numeric"] = pd.to_numeric(df_data2["Intensity [a.u]"], errors="coerce")
print(df_data2.head(5))
print(df_data2.dtypes)
print("-"*100)
# 新たに「astype」列と「to_numeric」列を作成していますが、「Intensity [a.u]」を置き換えてください。
df_data2["Intensity [a.u]"] = pd.to_numeric(df_data2["Intensity [a.u]"], errors="coerce")
df_data2 = df_data2[["Energy [keV]", "Intensity [a.u]", "scale"]]
print(df_data2.head(5))
print(df_data2.dtypes)
[課題2-2]
先ほど、df_data2の「Intensity [a.u]」列の"-"(ハイフン)をNaNに変換しました。
NaNの場合は行を削除してみましょう。
まずはdf_data2をdf_data2_2としてコピーしてください。
df_data2_2 = df_data2.copy()
削除ができたら、次のコマンドで確認してください。
print(df_data2_2.head(5))
print(df_data2_2.shape)
ヒント:dropna
# データフレームをコピー
df_data2_2 = df_data2.copy()
# Intensity [a.u]に欠測値がある行(レコード)を削除する。
df_data2_2.dropna(subset=["Intensity [a.u]"], inplace=True)
print(df_data2_2.head(5))
print(df_data2_2.shape)
[課題2-3]
まずはdf_data2をdf_data2_3としてコピーしてください。
df_data2_3 = df_data2.copy()
補完した結果は、「fillna」と「interpolate」列を追加して保存してください。
結果は次の命令文で確認してください。
print(df_data2_3.iloc[60:70])
ヒント:fillna、interpolate
# データフレームをコピー
df_data2_3 = df_data2.copy()
# ffillで欠測値を埋める
df_data2_3["fillna"] = df_data2_3["Intensity [a.u]"].fillna(method="ffill")
# ffillで欠測値を埋める
df_data2_3["interpolate"] = df_data2_3["Intensity [a.u]"].interpolate(limit_direction="both")
# 結果の表示
print(df_data2_3.iloc[60:70])
[課題3-1]
df_data2_2の「scale」列には、「Intensity [a.u]」を何倍すればよいか数値が入っています。
こちらを参照して計算した結果を「Intensity [a.u]」列に置き換えてみましょう。
変換ができたら、次のコマンドで確認してください。
print(df_data2_2)
ヒント:fancy、astype
# ffillで欠測値を埋める
df_data2_2["Intensity [a.u]"] = df_data2_2["Intensity [a.u]"] * df_data2_2["scale"].astype(float)
# 結果の表示
print(df_data2_2)
[課題4-1]
df_data2_2を可視化してみましょう。
X軸には「Energy [keV]」、Y軸には「Intensity [a.u]」を指定して折れ線グラフを描いてみよう。
ヒント:df.plot
# X軸に「Energy [keV]」、Y軸は「Intensity [a.u]」を指定する。
df_data2_2.plot(figsize=(12, 10), x="Energy [keV]", y="Intensity [a.u]")