この記事は古川研究室 Advent_calendar 18日目の記事です。
本記事は古川研究室の学生が学習の一環として書いたものです.内容が曖昧であったり表現が多少異なったりする場合があります.
はじめに
pandas で前処理していたときに,データに数値以外の要素が混入していて歯がゆい思いをしたので,記事としてまとめます.
また,本記事のコードは jupyter notebook を用いたものです.
扱うデータ
kaggle の 2,2k+ Scotch Whisky Reviews データセット
データの説明
スコッチウイスキーについてレビュワーが評価しているデータセットです.
データ数 2247,項目数 7 のデータです.
データの確認
# ライブラリの import
import pandas as pd
import numpy as np
# csv ファイルの読み取り
data = pd.read_csv('scotch_review.csv')
# データの表示
data.head()
本題
扱うデータに数値以外の型を持つ要素があるか確認
今回は項目の 'review.point'(評価点) と 'price'(価格) のみを使います.
それぞれの列のデータ型を見ていきます
# 型の確認
data[['review.point','price']].dtypes
'review.point'列に数値以外の要素が混ざっていそうですね.
次のコードで該当する列に数値以外の要素があるか判定できます.(※str 型の数値は True を返します)
#'price', 'review.point'列に数値型に変換できない要素があれば 'False' を返す.
data[['review.point', 'price']].apply(lambda s:pd.to_numeric(s, errors='coerce')).notnull().all()
数値以外の型を持つ要素の抽出及び変換
ここからは 'price' 列から,数値以外の型を持つ要素を抽出し,置換していきます.
まずは抽出です.
# 数値ではない型の要素の抽出
pic = data[['price']][data['price'].apply(lambda s:pd.to_numeric(s, errors='coerce')).isnull()]
pic
ここでは /set と /liter のデータは欠損値として扱い,他は数値型に変換します.
# ',' の削除,'/' が含まれる要素を欠損値で置換
change_data = pic['price'].str.replace(',','').mask(pic['price'].str.contains('/'), np.nan)
change_data
元データに変更を反映させます.
# 元データのコピーを作成し,該当箇所を置換
data_c = data.copy()
data_c.loc[pic.index,'price'] = change_data
最後に 'price' 列の数値を数値型に変換し,欠損値を含む行を削除します.
data_c['price'] = pd.to_numeric(data_c['price'], errors = 'ignore')
df = data_c.dropna()
終わりに
今回は pandas.DataFrame で数値以外の要素の抽出し,置換をしました.次回の記事では,この前処理をした Whisky Reviews データセットを可視化してみます.
付録
自分用にコードに使用していた関数の説明を載せておきます.
数値型に変換できない要素があるかどうかの判定
#'price', 'review.point'列に数値型に変換できない要素があれば 'False' を返す.
data[['review.point', 'price']].apply(lambda s:pd.to_numeric(s, errors='coerce')).notnull().all()
- to_numeric(arg, errors = 'coerce')
- arg (pd.Series) の各要素を数値型に変換する.変換できないときは,errors に渡す引数に応じて処理をする.今回は 'corece' なので,変換できない要素を欠損値 NaN に置換する.(default は 'raise')
- 関数名 = lamba 引数: 式
- 無名関数.以下関数と同じ働きをする.
def 関数名(引数):
return 式
- DataFrame.apply(関数, axis = 0)
- 関数の引数に DataFrame の要素を渡す.axis で渡し方(行方向か列方向)を選択する.
- DataFrame.notnull()
- pandas.DataFrame の各要素に対して欠損値ではないなら True,欠損値なら False を返す.
- DataFrame.all(axis = None)
- 行または列のすべての要素が True なら True を返す.
各要素の文字列の部分的な置換と,値そのものの置換
# ',' の削除,'/' が含まれる要素を欠損値で置換
change_data = pic['price'].str.replace(',','').mask(pic['price'].str.contains('/'), np.nan)
change_data
- Series.str.replace('文字列A', '文字列B')
- Series の各要素に含まれる '文字列A' を '文字列B' に変換
- Series.str.contains('文字列A')
- '文字列A' を含む要素を True,それ以外の要素を False として返す.
- Series.mask(arg, '値')
- arg(Series) の True の要素を '値' で置き換え,'False' の要素は変更しない.