RとPythonで前処理　json

#はじめに
またまたRの勉強会に参加しました
今回はデータの前処理です
データ処理の8割は前処理といわれるくらい前処理は多岐にわたると思いますが
今回は、問題のあるcsvファイルとjsonを入力して、前処理を施す、でした
目的は、Rの講習会の内容をpythonではどうやって書くの？を復習かねて記録することです

#環境
windows10 Pro 64bit
R :3.6.1
RStudio :1.2.1335

Google Colaboratoryを使用
Python :3.6.8

https://github.com/WillGardella/hotels/
内のjsonを利用

#なにするの
①問題のあるcsvファイルの入力
②正規表現で文字処理を行い、データフォーマットを変更する
③jsonファイルの入力
④入力したデータの利用



#Rのコード
①問題のあるcsvファイルの入力
ファイルの入力は、read.csv、read_csvなどを用いて読み込み
read_csvは、R標準のread.csvに比べ高速で便利な関数になります
↓参考にさせていただきました
https://heavywatal.github.io/rstats/readr.html

```R

dirty.csv

col1, col2, col3
"1,233", "$12.79", "$1,333,233.17"
"470", "$1,113.22", "$0.12"

#使用するpackage
library(readr)
library(dplyr)
library("jsonlite")
library("listviewer")
library("ndjson")
library("revgeo")
library("tidyverse")

#dirty.csvの読み込み
a2<-read_csv("dirty.csv")

> a2
# A tibble: 2 x 3
   col1 col2      col3         
  <dbl> <chr>     <chr>        
1  1233 $12.79    $1,333,233.17
2   470 $1,113.22 $0.12    
```
②正規表現で文字処理を行い、データフォーマットを変更する
データに\$が付いているため、strで読み込まれている
$を削除して数値に置き換える関数を定義して、col2とcol3に適用

```r

#"$"を削除して、数値に変換する関数を定義
clean <- function(ttt){
  as.numeric( gsub('[^a-zA-Z0-9.]', '', ttt))
}

#a2に関数cleanを適用しdataとする
data <- a2 %>% mutate(col2 = clean(col2),col3 = clean(col3))
> data
# A tibble: 2 x 3
   col1   col2       col3
  <dbl>  <dbl>      <dbl>
1  1233   12.8 1333233.  
2   470 1113.        0.12
```
③jsonファイルの入力
利用するデータは、hotels.json
コード内で調べますが、8076レコードのstreaming JSONをdataframeに読み込んでデータの概要をつかむ。

```R

#streaming JSONをdataframeに入力

df <- "data/hotels.json" %>%
  ndjson::stream_in()

#データの概要を確認
glimpse(df)

> glimpse(df)
Observations: 8,076
Variables: 25
$ activity         <chr> "sleep", "sleep", "sleep", "sleep", "sleep", "slee...
$ address          <chr> "Cwm Cadlan, Penderyn, CF44 0YJ", "Harbour Island,...
$ alt              <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, "Grand Hotel a...
$ checkin          <chr> NA, NA, NA, NA, NA, "14:00", NA, NA, NA, NA, NA, N...
$ checkout         <chr> NA, NA, NA, NA, NA, "10:00", NA, "12:00", NA, NA, ...
$ content          <chr> "Fantastic little B&B with 3 rooms, all en-suite. ...
$ directions       <chr> "From Penderyn, follow Cwm Cadlan road from Lamb H...
$ email            <chr> "willow.walks@hotmail.co.uk", NA, "info@porambahos...
$ fax              <chr> NA, NA, NA, NA, NA, NA, "+33 4 90 60 40 76", NA, N...
$ geo.lat          <dbl> 51.782300, 25.497250, -25.595870, 61.054100, 5.278...
$ geo.lon          <dbl> -3.495900, -76.636740, -54.567661, 28.191100, 115....
$ hours            <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ id               <dbl> 4042, 8848, 23350, 15189, 14992, 15540, 40356, 375...
$ image            <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, "https://en.wi...
$ name             <chr> "Beili Helyg Guest House", "Valentines Resort & Ma...
$ phone            <chr> "+44 0 1685 813609", "(866) 389-6864", "+54 3757 4...
$ price            <chr> "ﾂ｣80 per double room per night", NA, NA, "double ...
$ title            <chr> "Brecon Beacons National Park", "Eleuthera", "Puer...
$ tollfree         <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "+1-80...
$ type             <chr> "landmark", "landmark", "landmark", "landmark", "l...
$ url              <chr> "http://www.beilihelygguesthouse.co.uk", "http://w...
$ image_direct_url <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, "https://uploa...
$ city             <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ country          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
$ state            <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
```

④入力したデータの利用
例としてカラムの1つ、altの内容を確認。altは、6897/8076 欠損値であることが分かる。
文字化けを修正
GPSデータを抜き出してプロットしてみる。
世界中のhotelデータが登録されていることがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258389/51f8bf46-49c5-1b99-d752-56dd46d91eb3.png)

```r

df %>% count(alt) %>% arrange(-n)

# A tibble: 1,161 x 2
   alt                                  n
   <chr>                            <int>
 1 NA                                6897
 2 Peak District Cottages               4
 3 Best Western                         3
 4 Arresﾃｸ                              2
 5 Bed and Breakfast                    2
 6 Buda Panziﾃｳ                         2
 7 formerly Etap                        2
 8 formerly Etap Hotel                  2
 9 formerly Four Points by Sheraton     2
10 Hostel                               2
# ... with 1,151 more rows

#文字化け修正
for(i in 1:25){
  df[,i] <- df[,i] %>%
    iconv(from="utf-8",to="cp932")
}

#GPSデータをプロット
plot(df$geo.lon, df$geo.lat)

```


#Pythonのコード
①問題のあるcsvファイルの入力
pandasのread_csvでそのまま入力すると問題のあるcsvの意図通り?','を誤認識してしまいます

```python

import pandas as pd
a1 = pd.read_csv('dirty.csv')
a1

                    col1	col2	col3
1,233	"$12.79"	"$1	     333	233.17"
470	     "$1	    113.22"	"$0.12"	NaN
```
read_csvのパラメータ skipinitialspace=True にすると今回はうまく読み込めます

```python

a1 = pd.read_csv('dirty.csv', skipinitialspace=True)
a1

     col1	    col2	col3
0	1,233	  $12.79	$1,333,233.17
1	470	   $1,113.22	$0.12
```

②正規表現で文字処理を行い、データフォーマットを変更する
dataframeの各要素に対して処理を行う方法はいくつかあります
関数を適用する場合は、dataframe.applymap()などがありますが
今回は、正規表現を使うので、dataframe.replace()を使ってみます。regex＝Trueで全要素に正規表現が適用されます。
このままでは要素はobjectのままなのでfloatに変換します

```python

a1.replace('[^a-zA-Z0-9.]','',regex	= True , inplace=True)
a1=a1.astype(float)
a1


      col1	col2	col3
0	1233.0	12.79	1333233.17
1	470.0	1113.22	0.12

a1.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
col1    2 non-null float64
col2    2 non-null float64
col3    2 non-null float64
dtypes: float64(3)
memory usage: 128.0 bytes
```
③jsonファイルの入力
load 関数　：JSON ファイルをPythonの辞書型で保存する。
loads関数　：JSON 形式の文字列をpythonの辞書型で保存する。

hotels.jsonをopenすると、
<_io.TextIOWrapper name='hotels.json' mode='r' encoding='utf-8'>
で読み込まれます。strのイテレータなので（あってるのかな？）、1行づつloads関数で読み込んで
hotelsリストにappendしていきます。
load関数で読み込める場合は、1ラインずつ処理する必要ないのですが（おまけ参照）、、もっといい方法がありそう、、
loadとloadsでややこしい、、

```python

import json
hotels = []
with open('hotels.json',encoding='utf-8') as f:
  for i in f:
    hotel = json.loads(i)
    hotels.append(hotel)
```
hotelsリストは、そのままdataframeに変換できます。
しかし、このままではgeoデータがネストしてしまってます。

```python

hotels_df = pd.DataFrame(hotels)
hotels_df.head()

activity	address	alt	checkin	checkout	city	content	country	directions	email	fax	geo	hours	id	image	image_direct_url	name	phone	price	state	title	tollfree	type	url
0	sleep	Cwm Cadlan, Penderyn, CF44 0YJ	None	None	None	NaN	Fantastic little B&B with 3 rooms, all en-suit...	NaN	From Penderyn, follow Cwm Cadlan road from Lam...	willow.walks@hotmail.co.uk	None	{'lat': 51.7823, 'lon': -3.4959}	None	4042	None	NaN	Beili Helyg Guest House	+44 0 1685 813609	£80 per double room per night	NaN	Brecon Beacons National Park	None	landmark	http://www.beilihelygguesthouse.co.uk
1	sleep	Harbour Island, North Eleuthera, Bahamas	None	None	None	NaN	Valentines is the most vibrant and exciting lu...	NaN	None	None	None	{'lat': 25.49725, 'lon': -76.63674}	None	8848	None	NaN	Valentines Resort & Marina	(866) 389-6864	None	NaN	Eleuthera	None	landmark	http://www.valentinesresort.com/
2	sleep	None	None	None	None	NaN	Small, friendly and relaxed hostel, offering b...	NaN	El Urú 120, Puerto Iguazú,	info@porambahostel.com	None	{'lat': -25.59587, 'lon': -54.567661}	None	23350	None	NaN	Poramba Hostel	+54 3757 423041	None	NaN	Puerto Iguazú	None	landmark	http://porambahostel.com
3	sleep	Kauppakatu 52	None	None	None	NaN	Centrally located. The shower facilities are s...	NaN	None	None	None	{'lat': 61.0541, 'lon': 28.1911}	None	15189	None	NaN	Matkustajakoti Turisti-Lappee	+358 5 415 0800	double 51 €, single 31€	NaN	Lappeenranta	None	landmark	None
4	sleep	Lot 27-28, Jalan Muhibbah	None	None	None	NaN	a 2-star hotel. Rooms with A/C, attached toile...	NaN	None	hpl1@hpl-group.com.my	None	{'lat': 5.278967, 'lon': 115.241568}	None	14992	None	NaN	Pulau Labuan Hotel	+60 87416288	RM128-158	NaN	Labuan	None	landmark	http://www.hpl-group.com.my/hpl.html
```
pd.io.json.json_normalize()
で読み込むと、ネストをフラットにしてdataframeへ変換できます。
geoは、 geo.lat geo.lon に分割されます。

```python

hotels_df = pd.io.json.json_normalize(hotels)
hotels_df.head()

activity	address	alt	checkin	checkout	city	content	country	directions	email	fax	geo.lat	geo.lon	hours	id	image	image_direct_url	name	phone	price	state	title	tollfree	type	url
0	sleep	Cwm Cadlan, Penderyn, CF44 0YJ	None	None	None	NaN	Fantastic little B&B with 3 rooms, all en-suit...	NaN	From Penderyn, follow Cwm Cadlan road from Lam...	willow.walks@hotmail.co.uk	None	51.782300	-3.495900	None	4042	None	NaN	Beili Helyg Guest House	+44 0 1685 813609	£80 per double room per night	NaN	Brecon Beacons National Park	None	landmark	http://www.beilihelygguesthouse.co.uk
1	sleep	Harbour Island, North Eleuthera, Bahamas	None	None	None	NaN	Valentines is the most vibrant and exciting lu...	NaN	None	None	None	25.497250	-76.636740	None	8848	None	NaN	Valentines Resort & Marina	(866) 389-6864	None	NaN	Eleuthera	None	landmark	http://www.valentinesresort.com/
2	sleep	None	None	None	None	NaN	Small, friendly and relaxed hostel, offering b...	NaN	El Urú 120, Puerto Iguazú,	info@porambahostel.com	None	-25.595870	-54.567661	None	23350	None	NaN	Poramba Hostel	+54 3757 423041	None	NaN	Puerto Iguazú	None	landmark	http://porambahostel.com
3	sleep	Kauppakatu 52	None	None	None	NaN	Centrally located. The shower facilities are s...	NaN	None	None	None	61.054100	28.191100	None	15189	None	NaN	Matkustajakoti Turisti-Lappee	+358 5 415 0800	double 51 €, single 31€	NaN	Lappeenranta	None	landmark	None
4	sleep	Lot 27-28, Jalan Muhibbah	None	None	None	NaN	a 2-star hotel. Rooms with A/C, attached toile...	NaN	None	hpl1@hpl-group.com.my	None	5.278967	115.241568	None	14992	None	NaN	Pulau Labuan Hotel	+60 87416288	RM128-158	NaN	Labuan	None	landmark	http://www.hpl-group.com.my/hpl.html
```
変換したhotel_dfの概要
8076レコード数
25カラム
altのデータ数は、1179個（NaNが6897個）
でRの結果と同じですね

```python

hotels_df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8076 entries, 0 to 8075
Data columns (total 25 columns):
activity            8076 non-null object
address             7108 non-null object
alt                 1179 non-null object
checkin             1405 non-null object
checkout            1479 non-null object
city                376 non-null object
content             8076 non-null object
country             443 non-null object
directions          3356 non-null object
email               3048 non-null object
fax                 1638 non-null object
geo.lat             8076 non-null float64
geo.lon             8076 non-null float64
hours               37 non-null object
id                  8076 non-null int64
image               120 non-null object
image_direct_url    93 non-null object
name                8076 non-null object
phone               6690 non-null object
price               5095 non-null object
state               344 non-null object
title               8076 non-null object
tollfree            598 non-null object
type                8076 non-null object
url                 6945 non-null object
dtypes: float64(2), int64(1), object(22)
memory usage: 1.5+ MB
```


④入力したデータの利用
altの詳細とgeoデータのプロットをしてみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258389/3eb01adc-481a-8b83-93e4-3c6466c0ff46.png)


```python

hotels_df['alt'].value_counts(dropna=False)

NaN                                                  6897
Peak District Cottages                                  4
Best Western                                            3
Bed and Breakfast                                       2
formerly Etap Hotel                                     2
Buda Panzió                                             2
formerly Etap                                           2
Готель Україна                                          2
Arresø                                                  2
Napsugár Üdülő                                          2
Krogenberg Hegn                                         2
Peaceful stay in the sacred valley                      2
Hostel                                                  2
Гостиница «Интурист»                                    2
Near Castellana Grotte, Zoosafari and Alberobello       2
formerly Four Points by Sheraton                        2
Гостиница Турист                                        2
野中温泉                                                    1
Ukulhas Inn                                             1
info@dahliainn.com                                      1
名寄サンピラーユースホステル                                          1
Гостиница Stone                                         1
Hotel Los Cantaros                                      1
Felső-erdei Vendégház                                   1
沙流川温泉 ひだか高原荘                                            1
バックパッカーズ宮島                                              1
千姫物語                                                    1
formerly Casa de las Chimeneas                          1
Hotel Tókert Szálloda és Étterem                        1
Отель &quot;Miran International&quot;                   1
                                                     ... 
Alfréd Panzió                                           1
ริกก้า อินท์                                            1
Готельний комплекс Viсtoria                             1
鳥海大平キャンプ場                                               1
Кафе Польський Дім                                      1
Las Gaviotas Hotel & Apartments                         1
Formerly Village Haven Motel                            1
Belvárosi apartman                                      1
Napoleon Hotel Rome                                     1
Mátyás Hotel***                                         1
Kristály Hotel***                                       1
Ciklámen Faházak                                        1
ออรั่ม เดอะริเวอร์เพลส                                  1
Banyan Bed and Breakfast                                1
にしめ湯っ娘ランド                                               1
Pirwa backpackers La Paz                                1
Jagermeister Panzió                                     1
神戸ポートピアホテル                                              1
慢慢來民宿                                                   1
Kirkenes Snøhotell                                      1
Nopola cottages                                         1
formerly &quot;Green Court Hotel&quot;                  1
(forgot its name)                                       1
Árpád Panzió                                            1
Спутник                                                 1
Relais Santa Chiara                                     1
''Khan HaShayarot''                                     1
上士幌航空公園キャンプ場                                            1
宮沢海岸オートキャンプ場キャンパルわかみ                                    1
HI-Itasca State Park                                    1
Name: alt, Length: 1161, dtype: int64


import matplotlib.pyplot as plt
plt.scatter(hotels_df['geo.lon'],hotels_df['geo.lat'])
```


#おまけ　load関数での読み込み
github内のhotels.jsonは文字列でしたが、jsonフォルダ内のデータはjson形式でしたのでこちらも読み込んでみました。
'Review'と'HotelInfo'のkeyからなる辞書として読み込まれてます

```python

with open('72572.json', encoding='utf-8') as f:
  hotel = json.load(f)

hotel.keys()

dict_keys(['Reviews', 'HotelInfo'])
```
Reviewsは233レコードあるので、これをdataframeに変換
json形式の場合は、一括で読み込み可能なので楽です
元のデータに合わせて読み込みを変えていく必要があります

```python

jsn_pd = pd.io.json.json_normalize(jsn['Reviews'])
jsn_pd.head()


Author	AuthorLocation	Content	Date	Ratings.Business service (e.g., internet access)	Ratings.Check in / front desk	Ratings.Cleanliness	Ratings.Location	Ratings.Overall	Ratings.Rooms	Ratings.Service	Ratings.Sleep Quality	Ratings.Value	ReviewID	Title
0	gowharr32	Boston	We enjoyed the Best Western Pioneer Square. My...	March 29, 2012	NaN	NaN	5	5	5.0	5	4	4	4	UR126946257	“Excellent Hotel & Location”
1	Nancy W	Madison, Wisconsin	Great visit to Seattle thanks to our stay at t...	March 27, 2012	NaN	NaN	NaN	NaN	5.0	NaN	NaN	NaN	NaN	UR126795011	“Great Visit to Seattle!”
2	Janet H	Ketchikan, Alaska	Great Location,short walk from Amtrak station,...	March 27, 2012	NaN	NaN	5	5	5.0	5	5	5	5	UR126715331	“Excellent in Everyway”
3	TimothyFlorida	Florida	Accommodation in Seattle can be expensive. Thi...	March 24, 2012	NaN	NaN	5	5	5.0	4	5	4	5	UR126585393	“Great hotel, location & price.”
4	KarenArmstrong_BC	Armstrong, BC	Very cool old building in a great location. Ch...	March 13, 2012	NaN	NaN	4	5	4.0	3	3	3	3	UR126067021	“Cool place”

```