データクレンジング


ダーティデータ1(dirty data 1)

次のデータはメーカー本社ビルのお昼の天候情報である(仮想データ)。 このデータのデータクレンジングを行う。

d0 <- read.csv(file = 'https://stats.dip.jp/01_ds/data/dirty_data1.csv')

summary(d0) # 要約統計値 NA's:1 (NAが1つ含まれている)
##     会社名               気温            湿度             風速       
##  Length:22          Min.   :12.00   Min.   :-50.00   Min.   :-1.000  
##  Class :character   1st Qu.:20.00   1st Qu.: 30.00   1st Qu.: 1.000  
##  Mode  :character   Median :32.40   Median : 50.00   Median : 2.000  
##                     Mean   :28.18   Mean   : 39.73   Mean   : 2.052  
##                     3rd Qu.:34.10   3rd Qu.: 51.00   3rd Qu.: 4.000  
##                     Max.   :50.40   Max.   : 60.00   Max.   : 5.000  
##                     NA's   :1                        NA's   :1
library(DT)
datatable(d0)

NAを含むレコードを削除

d1 <- na.omit(d0)

summary(d1) # 要約統計値 NAがなくなった。
##     会社名               気温            湿度             風速       
##  Length:20          Min.   :12.00   Min.   :-50.00   Min.   :-1.000  
##  Class :character   1st Qu.:18.50   1st Qu.: 27.50   1st Qu.: 0.750  
##  Mode  :character   Median :32.40   Median : 50.00   Median : 2.000  
##                     Mean   :27.97   Mean   : 38.55   Mean   : 2.105  
##                     3rd Qu.:34.10   3rd Qu.: 51.00   3rd Qu.: 4.000  
##                     Max.   :50.40   Max.   : 60.00   Max.   : 5.000
datatable(d1)

気温,湿度,風速の範囲を定め異常データがあるレコードを削除

値の範囲は過去の最低値・最高値から大体の範囲を決める。

気象 数値範囲
気温 -20~50℃
湿度 0~100%
風速 0~70m/s
# 各気象変数の許容範囲に入っているか否かを示す論理式を作成
is.tp <- -20 <= d1$気温 & d1$気温 <=  50
is.hm <-   0 <= d1$湿度 & d1$湿度 <= 100
is.ws <-   0 <= d1$風速 & d1$風速 <=  70

summary(is.tp)
##    Mode   FALSE    TRUE 
## logical       2      18
summary(is.hm)
##    Mode   FALSE    TRUE 
## logical       1      19
summary(is.ws)
##    Mode   FALSE    TRUE 
## logical       1      19
# 適切な範囲のレコードだけを抽出する。
d2 <- d1[is.tp & is.hm & is.ws, ]

datatable(d2)

気温,湿度,風速の数値型を揃える

気象 数値型
気温 小数点第1位までの実数
湿度 整数
風速 整数
d3 <- d2
d3$気温 <- round(d2$気温, 1)
d3$湿度 <- round(d2$湿度, 0)
d3$風速 <- round(d2$風速, 0)

datatable(d3)

名寄せ(なよせ)

同じ内容で表記方法が異なるデータを統一する。

d3$会社名
##  [1] "ソニー"         "Sony"           "SONY"           "sony"          
##  [5] "ソニー株式会社" "Sony(株)"     "ソニー(株)"     "sony"          
##  [9] "富士通"         "Fujitsu"        "Fujitu"         "FUJITSU"       
## [13] "富士通株式会社" "富士通(株)"     "fujitsu"        "FUJITSU"
# ソニー株式会社を意味する表記
LAB.SONY <- c("ソニー", "Sony(株)", "ソニー(株)", "Sony", "SONY", "sony")

# 富士通株式会社を意味する表記
LAB.FUJITSU <- c("富士通", "富士通(株)", "Fujitsu", "FUJITSU", "fujitsu", "Fujitu", "fujitu")

# %in%の記号は右辺の集合に含まれるか否かを示す論理記号
is.sony    <- d3$会社名 %in% LAB.SONY
is.fujitsu <- d3$会社名 %in% LAB.FUJITSU

d4 <- d3

# 各メーカーの正式名称に統一
d4$会社名[is.sony]    <- 'ソニー株式会社'
d4$会社名[is.fujitsu] <- '富士通株式会社'

d4$会社名
##  [1] "ソニー株式会社" "ソニー株式会社" "ソニー株式会社" "ソニー株式会社"
##  [5] "ソニー株式会社" "ソニー株式会社" "ソニー株式会社" "ソニー株式会社"
##  [9] "富士通株式会社" "富士通株式会社" "富士通株式会社" "富士通株式会社"
## [13] "富士通株式会社" "富士通株式会社" "富士通株式会社" "富士通株式会社"
# クリーンデータ(clean data)
datatable(d4)

Python

import pandas as pd
d0 = pd.read_csv('https://stats.dip.jp/01_ds/data/dirty_data1.csv')
d0.head()
##        会社名    気温    湿度   風速
## 0      ソニー  14.0  50.0  4.0
## 1     Sony  38.2  54.0  1.1
## 2     SONY  20.4  20.0  0.0
## 3     sony  34.1  51.0  2.0
## 4  ソニー株式会社  20.0  60.0  4.0

NAを含むレコードを削除(Python)

d1 = d0.dropna()
d1
##            会社名       気温    湿度   風速
## 0          ソニー  14.0000  50.0  4.0
## 1         Sony  38.2000  54.0  1.1
## 2         SONY  20.4000  20.0  0.0
## 3         sony  34.1000  51.0  2.0
## 4      ソニー株式会社  20.0000  60.0  4.0
## 5      Sony(株)  32.4000  49.1  1.0
## 6       ソニー(株)  12.0000  30.0  5.0
## 7         sony  34.1000  51.0  2.0
## 8         SONY  50.4000  20.0  0.0
## 11         ソニー  14.0000 -50.0  4.0
## 12         富士通  14.0000  50.0  4.0
## 13     Fujitsu  38.2000  54.0  1.0
## 14      Fujitu  20.4000  20.0  0.0
## 15     FUJITSU  34.1000  51.0  2.0
## 16     富士通株式会社  20.0000  60.0  4.0
## 17  Fujitsu(株)  32.4000  49.0 -1.0
## 18      富士通(株)  12.0000  30.0  5.0
## 19     fujitsu  34.1134  51.0  2.0
## 20     FUJITSU  50.4000  20.0  0.0
## 21     FUJITSU  34.1000  51.0  2.0

気温,湿度,風速の範囲を定め異常データがあるレコードを削除(Python)

is_tp = (-20 <= d1['気温']) & (d1['気温'] <=  50)
is_hm = (  0 <= d1['湿度']) & (d1['湿度'] <= 100)
is_ws = (  0 <= d1['風速']) & (d1['風速'] <=  70)

d2 = d1[is_tp & is_hm & is_ws]
d2
##         会社名       気温    湿度   風速
## 0       ソニー  14.0000  50.0  4.0
## 1      Sony  38.2000  54.0  1.1
## 2      SONY  20.4000  20.0  0.0
## 3      sony  34.1000  51.0  2.0
## 4   ソニー株式会社  20.0000  60.0  4.0
## 5   Sony(株)  32.4000  49.1  1.0
## 6    ソニー(株)  12.0000  30.0  5.0
## 7      sony  34.1000  51.0  2.0
## 12      富士通  14.0000  50.0  4.0
## 13  Fujitsu  38.2000  54.0  1.0
## 14   Fujitu  20.4000  20.0  0.0
## 15  FUJITSU  34.1000  51.0  2.0
## 16  富士通株式会社  20.0000  60.0  4.0
## 18   富士通(株)  12.0000  30.0  5.0
## 19  fujitsu  34.1134  51.0  2.0
## 21  FUJITSU  34.1000  51.0  2.0

気温,湿度,風速の数値型を揃える(Python)

d3 = d2
d3 = d2.round({'気温':1, '湿度':0, '風速':0})
d3
##         会社名    気温    湿度   風速
## 0       ソニー  14.0  50.0  4.0
## 1      Sony  38.2  54.0  1.0
## 2      SONY  20.4  20.0  0.0
## 3      sony  34.1  51.0  2.0
## 4   ソニー株式会社  20.0  60.0  4.0
## 5   Sony(株)  32.4  49.0  1.0
## 6    ソニー(株)  12.0  30.0  5.0
## 7      sony  34.1  51.0  2.0
## 12      富士通  14.0  50.0  4.0
## 13  Fujitsu  38.2  54.0  1.0
## 14   Fujitu  20.4  20.0  0.0
## 15  FUJITSU  34.1  51.0  2.0
## 16  富士通株式会社  20.0  60.0  4.0
## 18   富士通(株)  12.0  30.0  5.0
## 19  fujitsu  34.1  51.0  2.0
## 21  FUJITSU  34.1  51.0  2.0

名寄せ(なよせ)(Python)

# ソニー株式会社を意味する表記
LAB_SONY = {"ソニー", "Sony(株)", "ソニー(株)", "Sony", "SONY", "sony"}

# 富士通株式会社を意味する表記
LAB_FUJITSU = {"富士通", "富士通(株)", "Fujitsu", "FUJITSU", "fujitsu", "Fujitu", "fujitu"}

for i, row in d3.iterrows():
  if row['会社名'] in LAB_SONY:
    d3.at[i, '会社名'] = 'ソニー株式会社'
    
for i, row in d3.iterrows():
  if row['会社名'] in LAB_FUJITSU:
    d3.at[i, '会社名'] = '富士通株式会社'

d3
##         会社名    気温    湿度   風速
## 0   ソニー株式会社  14.0  50.0  4.0
## 1   ソニー株式会社  38.2  54.0  1.0
## 2   ソニー株式会社  20.4  20.0  0.0
## 3   ソニー株式会社  34.1  51.0  2.0
## 4   ソニー株式会社  20.0  60.0  4.0
## 5   ソニー株式会社  32.4  49.0  1.0
## 6   ソニー株式会社  12.0  30.0  5.0
## 7   ソニー株式会社  34.1  51.0  2.0
## 12  富士通株式会社  14.0  50.0  4.0
## 13  富士通株式会社  38.2  54.0  1.0
## 14  富士通株式会社  20.4  20.0  0.0
## 15  富士通株式会社  34.1  51.0  2.0
## 16  富士通株式会社  20.0  60.0  4.0
## 18  富士通株式会社  12.0  30.0  5.0
## 19  富士通株式会社  34.1  51.0  2.0
## 21  富士通株式会社  34.1  51.0  2.0

次はRチャンクで作成(RのdatatableでPythonデータを表示)

library(reticulate)
datatable(py$d3)

演習課題

次のデータをクレンジングせよ。 なお,全天日射量の上限は4.00MJとせよ。

dirty_data2.csv

ダーティデータ2(dirty data 2)

d <- read.csv(file = 'https://stats.dip.jp/01_ds/data/dirty_data2.csv')

datatable(d)