LoginSignup
21
21

More than 3 years have passed since last update.

pandas.DataFrame で数値以外の要素の抽出

Last updated at Posted at 2019-12-19

この記事は古川研究室 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

kata.jpg

'review.point'列に数値以外の要素が混ざっていそうですね.
次のコードで該当する列に数値以外の要素があるか判定できます.(※str 型の数値は True を返します)

#'price', 'review.point'列に数値型に変換できない要素があれば 'False' を返す.
data[['review.point', 'price']].apply(lambda s:pd.to_numeric(s, errors='coerce')).notnull().all()

kata.jpg

数値以外の型を持つ要素の抽出及び変換

ここからは '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

str_data.jpg

元データに変更を反映させます.

# 元データのコピーを作成し,該当箇所を置換
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' の要素は変更しない.
21
21
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21