ここではPythonのライブラリの中でもっとも頻繁に利用されるPandasを徹底的に使いこなすために「Python+Pandasシリーズ」として、
PandasのDataFrameにデータをロード(作成)する方法を解説します。
PandasにはExcelファイル、CSVファイル、タブ区切りのテキストファイル、データベースなどからデータを取り込む機能があります。
外部ファイルからデータを取り込む方法については別記事にて解説します。
ここではテスト的に使用する数件のデータを作成する方法を中心に説明します。
余談ですが、Pandasを学ぶには、ここで解説しているように10件くらいのテストデータを作成して学ぶことをお勧めします。
たとえば、Pandasのgroupby(), concat(), merge()メソッドを学ぶときは10件程度の少量のテストデータを作成して検証します。
ここではVisula Studio Code(VSC)の「Python Interactive window」
を使用してJupter(IPython Notebook)のような環境で説明します。
VSCを通常の環境からインタラクティブな環境に切り換えるにはコードを記述するときコメント「# %%」を入力します。
詳しい、操作手順については「ここ」
を参照してください。
インタラクティブな環境では、Pythonの「print(), plt.show()」などを使う必要がないので掲載しているコードでは省略しています。
VSCで通常の環境で使用するときは、必要に応じて「print(), plt.show()」等を追加してください。
この記事では、Pandas、Matplotlibのライブラリを使用しますので
「記事(Article001) | 記事(Article002) | 記事(Article003) | 記事(Article004)」
を参照して事前にインストールしておいてください。
Pythonのコードを入力するときにMicrosoftのVisula Studio Codeを使用します。
まだ、インストールしていないときは「記事(Article001)」を参照してインストールしておいてください。
説明文の左側に図の画像が表示されていますが縮小されています。
画像を拡大するにはマウスを画像上に移動してクリックします。
画像が拡大表示されます。拡大された画像を閉じるには右上の[X]をクリックします。
画像の任意の場所をクリックして閉じることもできます。
-
Pythonのdict型で定義したデータをPandasのDataFrameにロードする
行2-5ではPythonのライブラリを取り込んでいます。
行6ではPythonの警告メッセージをを抑止しています。
行10-15ではPhtyonに取り込むデータを「dict」型で定義しています。
行16ではPandasのDataFrame()メソッドでDataFrameにデータを取り込んでいます。
行17ではPandasのto_datetime()メソッドでstr型の日付をdatetime型に変換しています。
日付が「yyyy/mm/dd」の形式になっているときに「format='%Y/%m/%d'」のように指定します。
また、日付に時刻「hh:mm:ss」も含まれるときは「format='%Y/%m/%d %H:%M:%S'」のように指定します。
# Import the necessary libraries
import pandas as pd
import datetime as dt
import numpy as np
import warnings
warnings.simplefilter('ignore')
# %%
# Create DataFrame from dict
data = {
'category_name': ['JavaScript','jQuery','Python','C++','C#'],
'page_view': [100,150,900,600,700],
'exclude_me': [False, True, False, False, False],
'date_added': ['2021-10-01','2021-10-02','2021-10-25','2021-10-30','2021-10-31']
}
df = pd.DataFrame(data)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y-%m-%d') # Convert string to datetime format
#df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d') # Convert string to datetime format
#df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d %H:%M:%S') # Convert string to datetime format
#print(df.info())
図1はVisual Studio Code(VSC)の画面です。
VSCのインタラクティブ・ウィンドウから「df.info()」、「df.head()」を入力してPandasのDataFrameの構造とデータの中身を表示しています。
-
Pythonのlist型で定義したデータをPandasのDataFrameにロードする
行2ではDataFrameのindexのデータをlist型で定義しています。
行3ではDataFrameの列名をlist型で定義しています。
行4ではDataFrameに取り込む空のデータをlist型で定義しています。
行6-9ではlist型の変数「data」にDataFrameのレコード(行)をappend()メソッドで追加しています。
行11ではPandasのDataFrame()メソッドでデータを取り込んでいます。
DataFrameにindexも取り込むときは行12のようにDataFrame()の引数に「index=indices」を追加します。
行13のように特定の列「date_added」を除外することもできます。
行14ではPandasのto_datetime()メソッドでstr型の日付をdatetime型に変換しています。
str型の日付が「yyyy/mm/dd HH:MM:SS」の形式になっているので引数に「format='%Y/%m/%d %H:%M:%S'」を指定しています。
# Add Rows One By One To Data
indices = ['a','b','c','d','e']
columns = ['category_name', 'page_view', 'exclude_me', 'date_added']
data = []
data.append(['JavaScript', 100, False, '2021/10/01 11:29:59'])
data.append(['jQuery', 150, True, '2021/10/02 12:13:15'])
data.append(['Python', 900, False, '2021/10/25 05:06:59'])
data.append(['C++', 600, False, '2021/10/30 03:05:02'])
data.append(['C#', 700, False, '2021/10/31 01:02:03'])
df = pd.DataFrame(data, columns=columns)
#df =pd.DataFrame(data, columns=columns, index=indices)
#df = pd.DataFrame.from_records(data, exclude=['date_added'], columns=columns, index=indices)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d %H:%M:%S') # Convert string to datetime format
#print(df)
図2はVisual Studio Code(VSC)の画面です。
VSCのインタラクティブ・ウィンドウから「df.info()」、「df.head()」を入力してPandasのDataFrameの構造とデータの中身を表示しています。
-
PandasのDataFrameにロードされた不正なデータを修正する
行2-8ではPandasのDataFrameに取り込む列名とデータを定義しています。
ここでは、意図的に不正なデータを定義しています。
ハイライトされている箇所が不正なデータです。
行10ではPandasのDataFrameにデータを取り込んでいます。
行11ではstr型の日付をdatetime型に変換しています。
ここではPandasのto_datetime()メソッドの引数に「errors='coerce'」を指定しています。
「errors='coerce'」を追加すると不正なデータを検出してもエラーを無視して処理を続行します。
この指定がないと不正なデータを検出すると異常終了します。
日付が不正なときはPandasは「NaT(Not a Time)」を格納します。
行13-14ではPandasのisnull()メソッドで不正なデータ件数を表示しています。
行17-18では列「page_view」の不正なデータ「NaN(Not a Number)」を「0」で置換しています。
さらに列のデータ型を「int」型に変換しています。
参考までにDataFrameの列に「NaN」が値が含まれているときは、その列のデータ型は「float」型になります。
行21-22ではDataFrameから「datettime」型の列(Series)を抽出して不正なデータ「NaT(Not a Time)」を今日の日付で置換しています。
行21のselect_dtypes()メソッドでは列「date_added」が抽出されます。
したがって、行22では列「date_added」の不正な日付が置換されます。
行25-26では列「exclude_me」の不正なデータ「None」を「False」で置換しています。
さらに列「exclude_me」のデータ型を「bool」型に変換しています。
参考までに列に「None」が含まれるときはその列のデータ型は「object(str)」型になります。
行29では列「category_name」の不正なデータ「None」を「Null Data」に置換しています。
# Ignore invalid data and fixed it
columns = ['category_name', 'page_view', 'exclude_me', 'date_added']
data = []
data.append(['JavaScript', np.nan, False, '2021/10/01 11:29:59']) # invalid page_view
data.append(['jQuery', 200, None, '2021/10/02 12:13:15']) # a null value exclude_me
data.append(['Python', 900, False, '9999/99/99 05:06:59']) # invalid date_added(date)
data.append(['C++', 600, False, '2021/10/30 99:99:99']) # invalid date_added(time)
data.append([None, 700, True, '2021/10/31 01:02:03']) # a null value category_name
df = pd.DataFrame(data, columns=columns)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y-%m-%d %H:%M:%S', errors='coerce') # Convert string to datetime format => NaT
#print(f'df.isnull().sum():{df.isnull().sum()}')
#print(f'df.isnull().sum().sum() = {df.isnull().sum().sum()}')
# Fix page_view: NaN => 0, float => int
df['page_view'] = df['page_view'].fillna(0)
df['page_view'] = df['page_view'].astype('int') # int8, int16, int32, int64
# Fix add_added: NaT => today
dt_cols = df.select_dtypes(include=['datetime'])
df[dt_cols.columns] = dt_cols.fillna(pd.to_datetime('today'))
# Fix exclude_me: None => False
df['exclude_me'] = df['exclude_me'].fillna(False)
df['exclude_me'] = df['exclude_me'].astype('bool') # boolean
# Fix category_name: None => 'Null Data'
df['category_name'] = df['category_name'].fillna('Null Data')
#print(f'df.isnull().sum():\n{df.isnull().sum()}')
#df.info()
図3-1はソードコードの行11まで実行したときのVSCの画面です。
行11以降はコメントにしています。
まずは、「df.head()」で表示したDataFrameの中身を見てください。
ハイライトしているのが不正な値が格納されている箇所です。
列が「object」型のときは「Null Data」は「None」として表示されます。
列が「int」型のときは不正な値は「NaN(Not a Number)」として表示されます。
列が「bool」型のときは不正な値は「None」として表示されます。
列が「datetime」型のときは不正な値は「NaT(Not a Time)」として表示されます。
次に「df.info()」で表示したDataFrameの「Dtype」を見てください。
列「page_view」は本来「int」型のはずですが不正なデータ「NaN」があるので「float」型になっています。
なぜかと言えば、「NaN」は「float」型として変換されるからです。
列「exclude_me」は本来「bool」型のはずですが不正なデータ「None」があるので「object(str)」型になっています。
「None」は「object」型として変換されます。
列「date_added」は不正なデータ「NaT」があるのに「datetime」型になっています。
これは、Pandasのto_datetime()メソッドでstr型からdatetime型に変換するとき引数に「errors='coerce'」を指定しているからです。
「errors='coerce'」の指定があると、不正な日付があるときエラーを無視して「NaT」値を格納します。
「NaT」は「datetime」型として変換されます。
ちなみに、「errors='ignore'」を指定したときはエラーを無視して不正な日付をそのまま「object」型として格納します。
したがって列は「object」型になります。
「errors=''」の指定がないときはエラーとなって処理が中断されます。
図3-2はVSCのインタラクティブ・ウィンドウから「df.isnull().sum()」と「df」を入力して実行した画面です。
通常、PandasのDataFrame()メソッドで取り込んだデータに不正があるかどうかはDataFrameのisnull()メソッドを使用します。
画面に表示されているようにDataFrameには合計5個の不正なデータがあることは分かります。
図3-3はソードコードの行17-18のコメントを外して実行した後の画面です。
ここではVSCのインタラクティブ・ウィンドウから「df.info()」と「df」を入力して実行しています。
列「page_view」の不正なデータ「NaN」が「0」に置換されています。
そして列のデータ型が「float」型から「int」型に変わっています。
図3-4はソードコードの行21-22のコメントを外して実行した後の画面です。
ここではVSCのインタラクティブ・ウィンドウから「df.info()」と「df」を入力して実行しています。
列「date_added」の不正なデータ「NaT」が「today」の日付に置換されています。
図3-5はソードコードの行25-26のコメントを外して実行した後の画面です。
ここではVSCのインタラクティブ・ウィンドウから「df.info()」と「df」を入力して実行しています。
列「exclude_me」の不正なデータ「None」が「False」に置換されています。
そして列のデータ型が「object」型から「bool」型に変わっています。
図3-6はソードコードの行29のコメントを外して実行した後の画面です。
ここではVSCのインタラクティブ・ウィンドウから「df.info()」と「df」を入力して実行しています。
列「category_name」の不正なデータ「None」が「Null Data」に置換されています。
-
ここで解説したコードをまとめて掲載
最後にここで解説したすべてのコードをまとめて掲載しましたので参考にしてください。
# Article023_Python Pandas(Part1) Loading Data(1).py
# %%
# Import the necessary libraries
import pandas as pd
import datetime as dt
import numpy as np
import warnings
warnings.simplefilter('ignore')
# %%
# Create DataFrame from dict
data = {
'category_name': ['JavaScript','jQuery','Python','C++','C#'],
'page_view': [100,150,900,600,700],
'exclude_me': [False, True, False, False, False],
'date_added': ['2021-10-01','2021-10-02','2021-10-25','2021-10-30','2021-10-31']
}
#print(type(data))
df = pd.DataFrame(data)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y-%m-%d') # Convert string to datetime format
#df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d') # Convert string to datetime format
#df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d %H:%M:%S') # Convert string to datetime format
#print(df.info())
# %%
# Add Rows One By One To Data
indices = ['a','b','c','d','e']
columns = ['category_name', 'page_view', 'exclude_me', 'date_added']
data = []
data.append(['JavaScript', 100, False, '2021/10/01 11:29:59'])
data.append(['jQuery', 150, True, '2021/10/02 12:13:15'])
data.append(['Python', 900, False, '2021/10/25 05:06:59'])
data.append(['C++', 600, False, '2021/10/30 03:05:02'])
data.append(['C#', 700, False, '2021/10/31 01:02:03'])
df = pd.DataFrame(data, columns=columns)
#df =pd.DataFrame(data, columns=columns, index=indices)
#df = pd.DataFrame.from_records(data, exclude=['date_added'], columns=columns, index=indices)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y/%m/%d %H:%M:%S') # Convert string to datetime format
#print(df)
# %%
# Ignore invalid data and fixed it
columns = ['category_name', 'page_view', 'exclude_me', 'date_added']
data = []
data.append(['JavaScript', np.nan, False, '2021/10/01 11:29:59']) # invalid page_view
data.append(['jQuery', 200, None, '2021/10/02 12:13:15']) # a null value exclude_me
data.append(['Python', 900, False, '9999/99/99 05:06:59']) # invalid date_added(date)
data.append(['C++', 600, False, '2021/10/30 99:99:99']) # invalid date_added(time)
data.append([None, 700, True, '2021/10/31 01:02:03']) # a null value category_name
df = pd.DataFrame(data, columns=columns)
df['date_added'] = pd.to_datetime(df['date_added'], format='%Y-%m-%d %H:%M:%S', errors='coerce') # Convert string to datetime format => NaT
#print(f'df.isnull().sum():\n{df.isnull().sum()}')
#print(f'df.isnull().sum().sum() = {df.isnull().sum().sum()}')
# Fix page_view: NaN => 0, float => int
df['page_view'] = df['page_view'].fillna(0)
df['page_view'] = df['page_view'].astype('int') # int8, int16, int32, int64
# Fix add_added: NaT => today
dt_cols = df.select_dtypes(include=['datetime'])
df[dt_cols.columns] = dt_cols.fillna(pd.to_datetime('today'))
# Fix exclude_me: None => False
df['exclude_me'] = df['exclude_me'].fillna(False)
df['exclude_me'] = df['exclude_me'].astype('bool') # boolean
# Fix category_name: None => 'Null Data'
df['category_name'] = df['category_name'].fillna('Null Data')
#print(f'df.isnull().sum():\n{df.isnull().sum()}')
#df.info()
# %%