Pythonでデータ加工などを

前回は、ネットからCSVをダウンロードして、そのデータを加工して出力したりしたんですけど、元データの操作とかもできたりするので、ローカルに落とした上で、部分削除したり統計とったりしたいと思います。例のごとくインストールで苦戦したpandasを使って頑張ってみたいと思います。

余計な行を削除して反映させる

前回の記録では、いらない行があって削除するコマンドを実行しましたが、今回はもううざったいので削除した上で反映までさせてみます

import pandas as pd
file_path='./c01.csv'

#よみこんで
data=pd.read_csv(file_path,encoding="shift_jis")
#カットして
data.dropna(subset=['人口(女)'],inplace=True)
#出力
data.to_csv(file_path)

あ、しまった。文字コードがUTF-8で出力されてしまった。。。まぁ、別にいいか。

で、このファイルを使って今後色々操作していきたいと思います。encodingオプションはカットでいいか。

複数のカラムでインデックス、マルチインデックスで表示してみる

このファイル、よくよくみたら、一番左のカラムに名前がなく便宜上ナンバリングしてるようなので、カットするとして、都道府県名と西暦がユニークっぽいので、そこをインデックスにして表示してみます


import pandas as pd
file_path='./c01.csv'
data=pd.read_csv(file_path)

data2=data.iloc[:,1:].set_index(['都道府県名','西暦(年)'],drop=True)

print(data2.head())

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

あぁ、たぶんうまくいってる。ちょっとデータベースみたいになってきました。これをベースに色々作業をしてみます

group by でひとまとまりにしてみる

全国というデータがあるので、ひとまとまりってどうかと思いますけど、ひとまず都道府県別でこれまで記録した西暦における人口の和でも出してみます

と思ったら!このCSV、数値データの中に- という、ようは数値がなかったので、ハイフンを入れてやがったのです!通りでgroupby してもエラーが出ると思った!まだ初心者で練習中にも関わらず、例外が登場して本当に勉強になります!くそ公○員どもが!!

一旦、groupbyを進める前に元データで、数値のところに数値じゃないやつが入ってるものをNaNに変換して上書きしておきます

import pandas as pd
file_path='./c01.csv'
data=pd.read_csv(file_path)

#今回使うカラム3つにおいて、数値変換、エラーが出た場合、つまり数値以外が入ってる場合は、
#NaNにする。errorsのオプションは以下のとおり
#raise エラーがあることを返す
#coerce 例外部分はNaNで返す
#ignore 無視。そのまま
data['人口(総数)']=pd.to_numeric(data['人口(総数)'],errors="coerce")
data['人口(男)']=pd.to_numeric(data['人口(男)'],errors="coerce")
data['人口(女)']=pd.to_numeric(data['人口(女)'],errors="coerce")

data.to_csv('./c01.csv')

よし、うまく元データが変換できた。https://qiita.com/oystaar/items/b87b3f98f9913a6b119e を参考にしました。ありがとうございます。anomalocationさん!

さて、終わったところで、気を取り直してgroup byをためさないと

import pandas as pd
file_path='./c01.csv'
data=pd.read_csv(file_path)

#いらない一番左をカットしておいて。。
data2=data.iloc[:,1:]
#都道府県名を軸にgroupbyして、人口三種類をsumして表示と。。。
print(data2.groupby('都道府県名')['人口(総数)','人口(男)','人口(女)'].sum())

#実行結果
                   人口(総数)        人口(男)         人口(女)
都道府県名                                               
三重県          3.068043e+07   14867331.0  1.581310e+07
京都府          4.270636e+07   20881874.0  2.182448e+07
人口集中地区       7.626364e+08  374983170.0  3.876532e+08

~~

いや、できてはいるんだけど、pandasでgroup byする時に指数表記にしないでほしいんだけど…なにこれむかつく。
dtypesをみるに、floatだったから?整数部分が大きいから?
ネットでみると、間違ってません。そっちの方がみやすいですみたいな、頭の悪いコメントしてるバカがいたけど、お前のみやすさなんて関係ないし、指数表記がいやだっていってんだからいやなんだけどって思うわけで。

どうもオプションで変えられるらしい。ちょっと変更して実行

import pandas as pd
#フォーマットのオプション、小数点第一まで有効であとは無限ってことかな?
pd.options.display.float_format = '{:.1f}'.format
file_path='./c01.csv'
data=pd.read_csv(file_path)

#いらない一番左をカットしておいて。。
data2=data.iloc[:,1:]
#都道府県名を軸にgroupbyして、人口三種類をsumして表示と。。。
print(data2.groupby('都道府県名')['人口(総数)','人口(男)','人口(女)'].sum())

#実行結果
                  人口(総数)       人口(男)        人口(女)
都道府県名                                            
三重県           30680428.0  14867331.0   15813097.0
京都府           42706359.0  20881874.0   21824485.0

あぁ、うまくいった。pandasでgroup byがうまくいきました!よかった!

いや、ちょっと気が変わったんですけど、男女差 ってカラムがほしいです。このCSVに新しくカラムを追加することにしました。普通にカラム名をつけて代入するだけで完成します。mysqlに似てますね

import pandas as pd
#フォーマットのオプション、小数点第一まで有効であとは無限ってことかな?
pd.options.display.float_format = '{:.1f}'.format
file_path='./c01.csv'
data=pd.read_csv(file_path)

#いらない一番左をカットしておいて。。
data2=data.iloc[:,1:]
#都道府県名を軸にgroupbyして、人口三種類をsumして表示と。。。
data3=data2.groupby('都道府県名')['人口(総数)','人口(男)','人口(女)'].sum()

data3["男女差"]=data3['人口(男)']-data3['人口(女)']

print(data3)

#実行結果
                  人口(総数)       人口(男)        人口(女)         男女差
都道府県名                                                        
三重県           30680428.0  14867331.0   15813097.0   -945766.0
京都府           42706359.0  20881874.0   21824485.0   -942611.0
人口集中地区       762636365.0 374983170.0  387653195.0 -12670025.0
人口集中地区以外の地区  451105115.0 219468103.0  231637012.0 -12168909.0

よし!CSVに新しくカラムが追加できたぞ!やったね!

コメント