1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RとPythonで前処理 json

Last updated at Posted at 2019-09-16

はじめに

またまた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


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に適用


# "$"を削除して、数値に変換する関数を定義
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に読み込んでデータの概要をつかむ。


# 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


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の意図通り?','を誤認識してしまいます


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 にすると今回はうまく読み込めます


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に変換します


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でややこしい、、


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データがネストしてしまってます。


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 に分割されます。


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の結果と同じですね


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


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からなる辞書として読み込まれてます


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

hotel.keys()

dict_keys(['Reviews', 'HotelInfo'])

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


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

1
4
0

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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?