以前に整形した郵便番号データが綺麗に整形出来ているか、チェックするためにpandasを使います。しかし、pandasの使い方がよくわからなかったので、調べながら進めていくことにしました。読み込んだCSVファイルにヘッダーがないので、カラム(列)番号で抽出していきます。
もくじ
カラムの番号で抽出
import pandas as pd
df = pd.read_csv('20201130_zipcode_all_utf8.csv', header=None)
一つのカラム番号で抽出
df.iloc[:,0]
0 600000
1 640941
2 600041
3 600042
4 640820
...
124196 9071433
124197 9071751
124198 9071544
124199 9071800
124200 9071801
Name: 0, Length: 124201, dtype: int64
複数のカラム番号で抽出
df.iloc[:,[0,6]]
0 6
0 600000 NaN
1 640941 旭ケ丘
2 600041 大通東
3 600042 大通西(1〜19丁目)
4 640820 大通西(20〜28丁目)
... ... ...
124196 9071433 南風見仲
124197 9071751 波照間
124198 9071544 鳩間
124199 9071800 NaN
124200 9071801 与那国
[124201 rows x 2 columns]
範囲を指定して抽出
df.iloc[:,2:6]
2 3 4 5
0 サッポロシチュウオウク NaN 北海道 札幌市中央区
1 サッポロシチュウオウク アサヒガオカ 北海道 札幌市中央区
2 サッポロシチュウオウク オオドオリヒガシ 北海道 札幌市中央区
3 サッポロシチュウオウク オオドオリニシ(1-19チョウメ) 北海道 札幌市中央区
4 サッポロシチュウオウク オオドオリニシ(20-28チョウメ) 北海道 札幌市中央区
... ... ... ... ...
124196 ヤエヤマグンタケトミチョウ ハイミナカ 沖縄県 八重山郡竹富町
124197 ヤエヤマグンタケトミチョウ ハテルマ 沖縄県 八重山郡竹富町
124198 ヤエヤマグンタケトミチョウ ハトマ 沖縄県 八重山郡竹富町
124199 ヤエヤマグンヨナグニチョウ NaN 沖縄県 八重山郡与那国町
124200 ヤエヤマグンヨナグニチョウ ヨナグニ 沖縄県 八重山郡与那国町
[124201 rows x 4 columns]
重複した行を抽出
duplicated() と引数keep
duplicated()
引数keepを指定しないと、keep=’first’になり、重複した最初の行が、Falseになる。
duplicated(keep='first')
重複した最初の行が、Falseになる。
duplicated(keep='last')
重複した最後の行が、Falseになる。
duplicated(keep=False)
重複したすべての行が、Trueになる。
重複判定するカラムを指定:引数subset
headerをつけていれば、判定するカラムをカラム名で指定することができます。
df.duplicated(subset='カラム名')
df.duplicated(subset=['カラム名1', 'カラム名2'])
重複した行数をカウント:value_counts()
df.duplicated().value_counts()
duplicated()で得たTrueをカウントし、重複した行の数が確認できます。
引数keepによって、結果が変わります。
カラム番号を指定して重複行数をカウント
引数なし(keep=’first’)
df.iloc[:,0].duplicated().value_counts()
False 120360
True 3841
Name: 0, dtype: int64
引数 keep=False
df.iloc[:,0].duplicated(keep=False).value_counts()
False 119031
True 5170
Name: 0, dtype: int64
特定の文字列を含む行を抽出
完全一致:==
要素が文字列に完全一致すると、Trueになります。
特定の文字列を含む:str.contains()
要素が特定の文字列を含むと、Trueになります。
NaNの処理
要素がNaNである場合、デフォルトではTrueでもFalseでもなくNaNを返します。NaNだとstr.contains()を使って行を抽出するとエラーになります。
そこで、str.contains()の引数naでNaNの結果を置き換える値を指定します。
条件として使う場合、na=TrueとすればNaNの行も選択され、na=FalseとすればNaNの行は選択されません。
df.iloc[:,6].str.contains('、', na=True)
df.iloc[:,6].str.contains('、', na=False)
大文字小文字の処理:引数case
デフォルトでは大文字と小文字は区別して処理されます。引数caseをFalseとすると大文字小文字が区別されません。
条件を指定
&、|、~を使って条件を指定していきます。(and、or、notだとエラーになります)
ソースコード(python)
郵便番号データを整形するときに、「、()」の有無を条件として分岐しているので、整形に失敗していると、()が上手く閉じられていないはずです。そこで、片方の()が残っているデータと「、」が入っていて()がどちらもないデータを抽出していきます。
import pandas as pd
df = pd.read_csv('20201130_zipcode_all_utf8.csv', header=None)
par_start = df.iloc[:,6].str.contains('(', na=False)
par_end = df.iloc[:,6].str.contains(')', na=False)
comma = df.iloc[:,6].str.contains('、', na=False)
print(df[par_start & ~par_end])
print(df[~par_start & par_end])
print(df[comma & ~par_start & ~par_end])
結果
Empty DataFrame
Columns: [0, 1, 2, 3, 4, 5, 6]
Index: []
Empty DataFrame
Columns: [0, 1, 2, 3, 4, 5, 6]
Index: []
0 1 2 3 4 5 6
12566 295503 イワテケン ワガグンニシワガマチ アナアケ22チワリ、アナアケ23チワリ 岩手県 和賀郡西和賀町 穴明22地割、穴明23地割
12572 295523 イワテケン ワガグンニシワガマチ カツラゴザワ75チワリ、カツラゴザワ76チワリ 岩手県 和賀郡西和賀町 桂子沢75地割、桂子沢76地割
12573 295502 イワテケン ワガグンニシワガマチ カバサワ16チワリ、カバサワ17チワリ 岩手県 和賀郡西和賀町 樺沢16地割、樺沢17地割
12574 295512 イワテケン ワガグンニシワガマチ カワシリ40チワリ、カワシリ41チワリ 岩手県 和賀郡西和賀町 川尻40地割、川尻41地割
12591 295523 イワテケン ワガグンニシワガマチ サワナカ73チワリ、サワナカ74チワリ 岩手県 和賀郡西和賀町 沢中73地割、沢中74地割
12601 295522 イワテケン ワガグンニシワガマチ ナカムラ58チワリ、ナカムラ59チワリ 岩手県 和賀郡西和賀町 中村58地割、中村59地割
12603 295523 イワテケン ワガグンニシワガマチ ホソナイ68チワリ、ホソナイ69チワリ 岩手県 和賀郡西和賀町 細内68地割、細内69地割
12608 295523 イワテケン ワガグンニシワガマチ ヤナギザワ70チワリ、ヤナギザワ71チワリ 岩手県 和賀郡西和賀町 柳沢70地割、柳沢71地割
12609 295514 イワテケン ワガグンニシワガマチ ユガワ52チワリ、ユガワ53チワリ 岩手県 和賀郡西和賀町 湯川52地割、湯川53地割
12612 295505 イワテケン ワガグンニシワガマチ ユモト29チワリ、ユモト30チワリ 岩手県 和賀郡西和賀町 湯本29地割、湯本30地割
67796 4400833 アイチケン トヨハシシ イムレチョウニシヤマ、タカヤマ 愛知県 豊橋市 飯村町西山、高山
67804 4400032 アイチケン トヨハシシ イワタチョウイムラ、キタゴウナカ 愛知県 豊橋市 岩田町居村、北郷中
67805 4400041 アイチケン トヨハシシ イワタチョウミヤシタ、ミチアイ 愛知県 豊橋市 岩田町宮下、道合
72044 4411324 アイチケン シンシロシ イミチ、オクイミチ、ウチイミチ 愛知県 新城市 井道、奥井道、内井道
()が片方だけ残っているデータは0でした。
()が無く「、」が入っているデータは14件ありましたが、件数が少ないので元の郵便番号データ(KEN_ALL.CSV)をEXCELのフィルターにかけて確認してみます。
元から()が無く「、」だけで区切られているデータのようです。
他にも、isinを使って差分チェックもしましたが、一目でわかるようなミスはなかったので、あとは使いながら検証していくことにします。