散々インストールの時点でエラーをぶちかましてくれたpandasさん。問題解決に1.5時間もかかりましたが、英語ができないながらなんとかなったので、その分楽しませてもらおうと思います。それにしてもqiitaってサイトは便利ですね。頭があがりません。

CSVファイルを外部から読み込んでみる

なんか、サンプルがないかな?と色々探してみたところ、政府統計の国勢調査とか言うやつがありましたので、そこから男女別人口のデータを取得し、我がクソブログにアップロードしてみました。政府統計だから著作権がどうのとか言うまい。

で、そのurlを取得して表示するプログラムを書いてみました

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL)

#.headはデフォルトでは5行取得らしいよ
print(data.head())

#実行結果
エラーが
ごにょ
ごにょ

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte

ほんと、アンタはエラーが好きねぇ。

まぁ、英語ができない私が判断するに、文字コードの問題のような気がする。
そういえば、search consoleとかエクセルとかで吐き出されるCSVってshift jisだった気がする。

まさか政府統計もそうなの?頭おかしいんじゃないの?イマドキ?

ってことで、エンコードのオプション的なものをつけて実行してました

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.head())

#実行結果
  都道府県コード 都道府県名  元号  和暦(年)   西暦(年)    注    人口(総数)     人口(男)     人口(女)
0      00    全国  大正    9.0  1920.0  NaN  55963053  28044185  27918868
1      01   北海道  大正    9.0  1920.0  NaN   2359183   1244322   1114861
2      02   青森県  大正    9.0  1920.0  NaN    756454    381293    375161
3      03   岩手県  大正    9.0  1920.0  NaN    845540    421069    424471
4      04   宮城県  大正    9.0  1920.0  NaN    961768    485309    476459

やるじゃない!ちゃんと動くじゃない!よかったよかった。

ん、そういえば、会社でCSVを使った時、型ってもんがあったような…。文字列はクオーテーションだったはずで、数字はクオーテーションで囲んでなかったし。

CSVの中身の型を調べてみよう

型を調べるには、取得したデータの変数に対し、.dtypes をつけるだけでいいらしい。データタイプす と書いてあると覚えておこう。意味があってるか知らんけど

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.dtypes)

#実行結果
都道府県コード     object
都道府県名       object
元号          object
和暦(年)      float64
西暦(年)      float64
注           object
人口(総数)      object
人口(男)       object
人口(女)       object
dtype: object

ほう。。。一人前に色々と吐き出しおったわ。最後の「dtype: object」がよくわからんが、とはいえ、それぞれのタイプを判断してくれるとは、なかなか一人前な機能です。

floatはわかるとして、たぶん、他のCSVだと、INTなんかも出てきたりすることが予想できる。ところで、objectってなんだろうか…varcharとか、charとか、stringではないし。。。

このsamurai blogとか言う知識の塊みたいな便利サイト(https://www.sejuku.net/blog/62023)によると、どうもstrらしい。textのことらしい。了解

となると。。。たぶん、castとかもできるんだろう。floatからobjectとか。.astype(float)とかでできるらしい。さっきの便利サイトによると。了解。頭の片隅にいれておくことにします。

データの行数をカウントする

外部から読み込みはしたけれど、このデータって何行あるんだっけ?っていうのは、データを読み込んでlen()関数でチェックできる

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(len(data))

#実行結果
982

そういえば、このデータの一番下あたりの行、データではなくてコメントがわりに突っ込んでいたような気がする。なんでそんな使いづらいことをするんでしょうね。行政って。
つまり、CSVを読み込んだあと、何かしらの加工処理を行う必要がある場合が想定されるわけだ。

コメント部分をみると、3カラム目以降はデータがないわけですから、それが条件にマッチしたデータは消しておこう

各カラムのデータ欠損数を調べてみる

データがないところは、NaNで、isnull()でチェックできるので、ちょっとパターンをみてみます。
isnull()でチェックし、さらにsum()で合算できます

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.isnull().sum())

#実行結果
都道府県コード      0
都道府県名        2
元号           2
和暦(年)        2
西暦(年)        2
注          886
人口(総数)       2
人口(男)        2
人口(女)        2
dtype: int64

注は何か備考があれば入るところだからいいとして、人口とかの2と出てる部分、本来都道府県とかだったら絶対にnullのはずじゃないので、人口が2とかなってるところを削除します。

NaNを削除する。。。削除はdrop…dropnaという名前で実行できるらしいです。

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.dropna(subset=['人口(女)']))

#実行結果
<bound method DataFrame.sum of      都道府県コード  都道府県名     元号  和暦(年)  西暦(年)     注  人口(総数)  人口(男)  人口(女

〜〜
979      47   沖縄県  平成   27.0  2015.0  NaN   1433566    704619    728947

お、最後にあったメモみたいなのが消えた。こうやって加工するんですね。
dataの中身へ削除を反映させるには以下で実行

import pandas as pd
CSV_URL='ローカルファイル'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.dropna(subset=['人口(女)'],inplace=True))

inplaceをTrueで実行すると反映するらしいです。

てか、ふと思ったんだけど、都道府県と人口(総数)しかいらないんですよね。なので、その2つだけ取れたらいいのにいいのに。。。ってことで、特定のカラムを選択して取り出してみます。mysqlみたいですね。

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

print(data.dropna(subset=['人口(女)'])[['都道府県名','人口(総数)']])

#実行結果
    都道府県名    人口(総数)
0      全国  55963053
1     北海道   2359183
~~
~~
978  鹿児島県   1648177
979   沖縄県   1433566

先ほど、いらない部分を削除したやつの後ろに[]をつけて、中に必要なカラムをリスト型で指定するだけ。直感的表記でとてもいいですね。

ううん、左から何番目、上から何番目から何番目とか、スライスできたらいいのに…と思ったら、.ilocでできるらしいです。
さっきのデータから、抜き取ってみましょう

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")

#左から1列、上から1列のデータを取得
print(data.dropna(subset=['人口(女)'])[['都道府県名','人口(総数)']].iloc[0:1,0:1])

#実行結果
  都道府県名
0    全国

うん、綺麗に抜けた。でも。。。自動的にインクリメントされたかのような番号が邪魔ですね。。
メイン軸を設定すると消えるらしいです。都道府県をメイン軸に設定して再度実行

上のまま実行すると、軸しかない意味不明なものになるので、上から2、左から2まで取得した状態で、軸に対して人口(総数)が表示されるような状態にちょっと変更して実行

import pandas as pd
CSV_URL='http://webtopi.biz/csv/c01.csv'
data=pd.read_csv(CSV_URL,encoding="shift_jis")


print(data.dropna(subset=['人口(女)'])[['都道府県名','人口(総数)']].iloc[0:2,0:2].set_index('都道府県名'))

#実行結果
         人口(総数)
都道府県名          
全国     55963053
北海道     2359183

うん、軸は都道府県名、データは人口になってます。もし、スライスを0:1にしてると、軸はあるがデータがない状態になるので、emptyになるので注意が必要っぽい

ちょっと長くなってきたので、csvのデータ操作とかは次回にでも。

コメント