前処理大全[データ分析のためのSQL/R/Python実践テクニック]

サポートページ

この記事を読むのに必要な時間:およそ 0.5 分

お詫びと訂正(正誤表)

本書の以下の部分に誤りがありました。ここに訂正するとともに,ご迷惑をおかけしたことを深くお詫び申し上げます。

(2018年11月1日最終更新)

P.91 上部のSQLのコード(sql_2_awesome.sql)


-- ホテルテーブルからビジネスホテルのデータのみ抽出
WHERE hotel.is_business is True


-- ホテルテーブルからビジネスホテルのデータのみ抽出
  AND hotel.is_business is True

P.91 Pointの文章

このコードでは、JOIN句と同じクエリにWHERE句を指定しています。
このコードでは、ON句の結合条件に加えて、抽出条件を指定しています。

(以下2018年9月21日更新)

P.93

また、テーブル間で列名が異なるキーを結合キーとして設定することはできません。
テーブル間で列名が異なる場合は、left_onとright_on引数を利用してください。

P.107


result['before_price'] = \
  pd.Series(result['total_price'].groupby('customer_id').shift(periods=2))


result['before_price'] = \
  result['total_price'].groupby('customer_id').shift(periods=2)


(以下2018年7月20日更新)

P.169の5行目,6行目
P.171のRコードの解説2行目

P.64 r_awesome.r の解説3行目

自然数
ネイピア

(以下2018年6月12日更新)

P.64 r_awesome.r の解説3行目

reserve_tb.summary()のようにsummary関数を呼び出すことで、
reserve_tb %>% summary()のようにsummary関数を呼び出すことで

P.69 Point

data.frameのNAの置換によって実現しています。
coalesce関数によって実現しています。

P.73 ファイル名

r_awesome.R
r_not_awesome.R

P.80 python_awesome.pyの解説1行目

rank関数は、R同様に順位付けを行う関数です。
rank関数は、順位付けを行う関数です。

P.150 r_awesome.py

以下のコードに差し替えてください。


# ubBalance用のライブラリ
library(unbalanced)
library(tidyverse)

# percOverの設定値の計算
t_num <- production_tb %>% filter(fault_flg==T) %>% summarize(t_num=n())
f_num <- production_tb %>% filter(fault_flg==F) %>% summarize(f_num=n())
percOver <- round(f_num / t_num) * 100 - 100

# 不均衡を正す対象をfactor型に変換(logical型ではないことに注意)
# (第9章「9-1 カテゴリ型」の例題で解説)
production_tb$fault_flg <- as.factor(production_tb$fault_flg)

# ubBalance関数でオーバーサンプリングを実現、typeにubSMOTEを設定
# positiveは分類で少ない方の値を指定(指定しないことも可能だが警告が表示される)
# percOverは、元データから何%増やすかを設定
# (200なら3(200/100+1)倍、500なら6(500/100+1)倍となる。100未満の値は切り捨て)
# percUnderはアンダーサンプリングを行うときに必要だが、行わない場合は0で設定
# kはsmoteのkパラメータ
production_balance <-
  ubBalance(production_tb[,c('length', 'thickness')],
            production_tb$fault_flg,
            type='ubSMOTE', positive='TRUE',
            percOver=percOver, percUnder=0, k=5)

# 生成したfault_flgがTRUEのデータと元のfault_flgがFALSEのデータを合わせる
bind_rows(

  # production_balance$Xに生成したlengthとthicknessのdata.frameが格納
  production_balance$X %>%

    # production_balance$Yに生成したfault_flgのベクトルが格納
    mutate(fault_flg=production_balance$Y),

  # 元のfault_flgがFalseデータの取得
  production_tb %>%

    # factor型なので一致判定で取得
    filter(fault_flg == 'FALSE') %>%
    select(length, thickness, fault_flg)
)


(以下2018年5月18日更新)

P.112 python_awesome.py

以下のコードに差し替えてください。

# customer_idごとにreserve_datetimeでデータを並び替え
result = reserve_tb.groupby('customer_id') \
  .apply(lambda x: x.sort_values(by='reserve_datetime', ascending=True)) \
  .reset_index(drop=True)

# 新たな列としてprice_sumを追加
result['price_sum'] = pd.Series(
    # 必要なデータ列のみに絞り込み
    result.loc[:, ["customer_id", "total_price"]]

    # customer_idごとにtotal_priceのwindow3件にまとめ、その合計値を計算
    .groupby('customer_id')
    .rolling(center=False, window=3, min_periods=3).sum()

    # group化を解除すると同時に、total_priceの列を取り出し
    .reset_index(drop=True)
    .loc[:, 'total_price']
)

(以下2018年5月17日最終更新)

P.107 python_awesome.py 

以下のコードに差し替えてください。

# customerごとにreserve_datetimeで並び替え
# groupby関数のあとにapply関数を適用することによって、groupごとに並び替える
# sort_values関数によってデータを並び替え、axisが0の場合は行、1の場合は列を並び替え
result = reserve_tb \
  .groupby('customer_id') \
  .apply(lambda group:
         group.sort_values(by='reserve_datetime', axis=0, inplace=False))

# resultはすでに、customer_idごとにgroup化されている
# customerごとに2つ前のtotal_priceをbefore_priceとして保存
# shift関数は、periodsの引数の数だけデータ行を下にずらす関数
result['before_price'] = \
  pd.Series(result['total_price'].groupby('customer_id').shift(periods=2))

P116 python_not_awesome.py

以下のコードに差し替えてください。

# customer_idごとにreserve_datetimeでデータを並び替え
result = reserve_tb.groupby('customer_id') \
  .apply(lambda x: x.sort_values(by='reserve_datetime', ascending=True)) \
  .reset_index(drop=True)

# 新たな列としてprice_avgを追加
result['price_avg'] = pd.Series(
  result
    # customer_idごとにtotal_priceのwindow3件にまとめ、その平均値を計算
    # min_periodsを1に設定し、1件以上あった場合には計算するよう設定
    .groupby('customer_id')
    ['total_price'].rolling(center=False, window=3, min_periods=1).mean()

    # group化を解除すると同時に、customer_idの列を削除
    .reset_index(drop=True)
)

# customer_idごとにprice_avgを1行下にずらす
result['price_avg'] = \
  result.groupby('customer_id')['price_avg'].shift(periods=1)


(以下2018年5月15日更新)

P.65 Pythonによる前処理の3行目

NumPyライブラリのquantile関数
NumPyライブラリのpercentile関数

(以下2018年5月7日更新)

P.274 「12−1 日本測地系から正解測地系の変換,度分秒から度への変換」の10行目

「35度30分15秒」は30秒は0.25(15/60)分なので
「35度30分15秒」の15秒は0.25(15/60)分なので

P.171 Pythonによる前処理 コードの2行目


  reserve_tb['total_price'].apply(lambda x: np.log(x / 1000 + 1))


  reserve_tb['total_price'].apply(lambda x: np.log10(x / 1000 + 1))

P.171 Pythonによる前処理 コード解説1行目

NumPyライブラリのlog関数は対数を計算する関数です。1つ目の引数に対数化する値を指定します。2つ目の引数に対数の底を指定します。2つ目の引数を省略した場合は、10が対数の底に指定されます。
NumPyライブラリのlog関数は対数を計算する関数です。引数には対数化する値を指定します。log関数は対数の底に自然数が設定されます。log2関数を利用すると対数の底は2に設定され、同様にlog10関数では10が設定されます。

(以下2018年4月16日更新)

P88 図4.2 (INNER) JOINの右側のid_aの値

a_1 a_2 a_3
a_1 a_2 a_4

P195 sql_awesome.sqlの4行目から6行目

SELECT
  type,
  length,

  -- thicknessの欠損値を1で補完
  COALESCE(thickness, 1) AS thickness,
  fault_flg
FROM work.production_missn_tb
SELECT
  type,
  length,
  COALESCE(thickness,
           (SELECT AVG(thickness) FROM work.production_missn_tb))
    AS thickness,
  fault_flg
FROM work.production_missn_tb