表形式のデータに対する前処理

①対象データの確認と整備

最終的にどのようなデータにするべきなのかを明確に決めておく!

【データ要件】
 ・csv形式
 ・ヘッダーの項目は1行のみ
 ・pandasで取り込んだ後に可視化を行うことが出来る。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

②データの読み込みと内容確認


②-1.データの読み込み

・Excelファイルの場合、pandasのread_excel関数を利用します。
・引数として、
   ー io :読み込みたいデータのパス
   ー sheet_name:単一のシート名またはシート名のリストを指定し、特定のシートを読み込む。
# ライブラリのインポート
import pandas as pd

# データの読み込み
df_data = pd.read_excel(io='pop202003.xls',sheet_name='市町村別人口')


②-2.データの表示

・『読み込んだデータ.head()』:とすることでデータの先頭5行を表示。

In [1]: import pandas as pd
       df_data = pd.read_excel(io='pop202003.xls',sheet_name='市町村別人口')
       df_data.head()

Out[1]:    市町村別人口 ( 対 前月,対 前年  比較 )            Unnamed: 1  \
       0  Population by Cities, Towns and Villages                  NaN   
       1                                       NaN                  NaN   
       2                                       NaN                43891   
       3                                       NaN  2020-03-01 00:00:00   
       4                                       NaN  2020-03-01 00:00:00   

                              Unnamed: 2 Unnamed: 3 Unnamed: 4  \
       0                             NaN        NaN        NaN   
       1  対前月 Change over previous month        NaN        NaN   
       2                           43862      増 減 数      増 減 率   
       3             2020-02-01 00:00:00        NaN        NaN   
       4             2020-02-01 00:00:00     number       rate   

                             Unnamed: 5 Unnamed: 6 Unnamed: 7  
       0                            NaN        NaN        NaN  
       1  対前年 Change over previous year        NaN        NaN  
       2                          43525      増 減 数      増 減 率  
       3            2019-03-01 00:00:00        NaN        NaN  
       4            2019-03-01 00:00:00     number       rate  


・『DataFrameが代入された変数.shape』:出力結果は、(行数, 列数)にタプル型。

In [2]: import pandas as pd
       df_data = pd.read_excel(io='pop202003.xls',sheet_name='市町村別人口')
       print(df_data.shape)
Out[2]: (67, 8)
  ・列だけ抽出するとき:.shape[1]
  ・行だけ抽出するとき:.shape[0]


②-3.変数データ型の確認

変数のデータ型に応じて、適用できる関数や行うことのできる処理が異なる為、データ型を把握することは非常に重要。

【代表的なデータ型】
ー数値
   ・int型:整数
   ・float型:浮動小数点数
   ・bool型:真偽値(1 or 0であるが、PythonではTrue or Falseとも表現される)
ー文字列
   ・str型:文字列(但し、pandasを利用した場合、このデータ型はobjectと表示されます)


・DataFrameが代入された変数.info()
   →DataFrameの各カラムのデータ型を確認するには、info関数を利用。

In[1]: import pandas as pd
      df_data = pd.read_excel(io='pop202003.xls',sheet_name='市町村別人口')
      print(df_data.info())

Out[1]: <class 'pandas.core.frame.DataFrame'>
       RangeIndex: 67 entries, 0 to 66
       Data columns (total 8 columns):
        市町村別人口 ( 対 前月,対 前年  比較 )     53 non-null object
       Unnamed: 1                    52 non-null object
       Unnamed: 2                    53 non-null object
       Unnamed: 3                    51 non-null object
       Unnamed: 4                    51 non-null object
       Unnamed: 5                    53 non-null object
       Unnamed: 6                    51 non-null object
       Unnamed: 7                    51 non-null object
       dtypes: object(8)
       memory usage: 4.3+ KB
       None

dtypes: object(8)とあるため、全てのデータのデータ型が現状はobjectと判断されています。
今後前処理を行なっていき、数値としてのデータを持つカラムのデータ型はobjectから数値型への変更を行う。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


③表形式のデータに対しての前処理


③-1.ヘッダーの変更

【前処理前のヘッダー】

画像1

・pandasでデータ分析を行う際にはヘッダーの要素は1行で判定するため、上記の複数の要素を1つにまとめる必要がある。


・データのヘッダーは.columnsで得ることができます。

# ヘッダーの変更
df_data.columns = ['市町村名', '2020-03-01_人口', '2020-02-01_人口', '2020-02-01_増減数','2020-02-01-増減率', '2019-02-01_人口', '2019-02-01_増減数', '2019-02-01_増減率']



③-2.不要な表の削除1

・行削除を行う場合、『.drop( )』を用い、引数として削除したい行のインデックスをリスト形式で指定する。

df_data = df_data.drop([0,1,2,3,4])
df_data.head()


・次のタスクでも引き継ぐためのデータをCSV形式で保存。

 『to_csv( )』

     ・引数①『path_or_buf 』:保存したいデータ。
     ・引数②『index』:インデックスを加味するか?(True or False)

df_data.to_csv(path_or_buf='pop202003_version1.csv',index=False)



③-3.欠損値の削除

 『.isnull( )』

   →欠損であるか否かの真理値を表ごとに返してくれる。
    ・欠損がある:True
    ・欠損がない:False

In [2]: df_data['2020-03-01_人口'].isnull()

Out[2]: 0     False
       1      True
       2     False
       3      True
       4     False
             ...  
       57     True
       58    False
       59     True
       60    False
       61    False
       Name: 2020-03-01_人口, Length: 62, dtype: bool

これを使って、

欠損値が含むデータを抽出する場合。

In [3]: df_data[df_data['2020-03-01_人口'].isnull()]

Out[3]: 市町村名  2020-03-01_人口  2020-02-01_人口  2020-02-01_増減数  \
       1             (Cities)            NaN            NaN             NaN   
       3                  NaN            NaN            NaN             NaN   
       15  (Towns & Villages)            NaN            NaN             NaN   
       ・・・
       57                 NaN            NaN            NaN             NaN   
       59                 NaN            NaN            NaN             NaN   

           2020-02-01-増減率  2019-02-01_人口  2019-02-01_増減数  2019-02-01_増減率  
       1              NaN            NaN             NaN             NaN  
       3              NaN            NaN             NaN             NaN  
       15             NaN            NaN             NaN             NaN  
       ・・・
       57             NaN            NaN             NaN             NaN  
       59             NaN            NaN             NaN             NaN  


欠損値を含まないデータのみを抽出。

In [4]: df_data[~df_data['2020-03-01_人口'].isnull()]

Out[4]:         市町村名  2020-03-01_人口  2020-02-01_人口  2020-02-01_増減数  \
       0        県    計 Okinawa-ken      1457451.0      1457163.0           288.0   
       2             市 部 計 All shi      1127260.0      1126982.0           278.0   
       ・・・ 
       60       竹 富 町 Taketomi-cho         4108.0         4093.0            15.0   
       61        与那国町 Yonaguni-cho         2078.0         2079.0            -1.0   

           2020-02-01-増減率  2019-02-01_人口  2019-02-01_増減数  2019-02-01_増減率  
       0         0.019764      1451392.0          6059.0        0.417461  
       2         0.024668      1122351.0          4909.0        0.437385  
       4        -0.012893       318482.0          -531.0       -0.166728  
       ・・・
       60        0.366479         4075.0            33.0        0.809816  

※裏を取るときは条件に対して、『~』否定演算子を用います。


また、現状でのデータを次のタスクでも引き継ぐため、データをcsv形式で保存しておきましょう。

df_data = df_data[~df_data['2020-03-01_人口'].isnull()]
df_data.to_csv(path_or_buf='pop202003_version2.csv',index=False)



③-4.半角空白の削除

  『.replace(  )』

     ・第1引数:置換したい元の文字列
     ・第2引数:置換した後の文字列

In [2]: test_string = '県    計 Okinawa-ken'

       def remove_hankaku(x):

           return str(x).replace(' ', '')

       print(remove_hankaku(test_string))


Out [2]:県計Okinawa-ken     

上記のように引数に空白置換した文字列を指定することで、空白を削除してくれます。
またpandasの各々のレコードに定義した関数の処理を行うためには、.map()を用います。
mapを用いることで各々のレコードに対して、個別に処理を行うことなく前処理を行うことが可能となります。

In [3]: df_data['市町村名'].map(remove_hankaku)            

Out [3]:0     県計Okinawa-ken
       2     市部計Allshi
       ・・・
       60    竹富町Taketomi-cho
       61    与那国町Yonaguni-cho
       Name: 市町村名, dtype: object



③-5.日本語と英字の分割

 『.isupper( )』

     →文字が大文字かどうか判定できる。(True or False)

In [1]: import pandas as pd
       df_data = pd.read_csv('pop202003_version3.csv')
       df_data['市町村名']

Out [1]:0              県計Okinawa-ken
       1                  市部計Allshi
       ...
       47           竹富町Taketomi-cho
       48          与那国町Yonaguni-cho
       Name: 市町村名, dtype: object     
In [2]: test_string = '竹富町Taketomi-cho'
       for index,string in enumerate(test_string):
           print(string.isupper())

Out [2]: False
       False
       False
       True
       ・・・
       False
       False
       False    

for文を用いて文字列の一文字目から最後までの文字1つ1つに対して、『.isupper( )』を用いる。

 『enumerate』

   →要素のインデックスと要素を同時に取り出すことが可能。


境界の判断が出来たので、2分割すればうまく分けることが可能。
(アルファベットの大文字が境目となっている。)


# ライブラリのインポート
import pandas as pd

# データの読み込み
df_data = pd.read_csv('pop202003_version3.csv')
 #関数設定 
def get_ja_name(x):
   ja_name = ''
   for num,i in enumerate(x):
       if(i.____()):
           ja_name = x[____]
           break;
   return ja_name
   
def get_en_name(x):
   en_name = ''
   for num,i in enumerate(x):
       if(i.____()):
           en_name = x[____]
           break;
   return en_name

# 日本語の取得
ja_name_list = df_data[____].map(____)

# 英字の取得
en_name_list = df_data[____].map(____)

# pandasに代入
df_data['市町村名'] = ____
df_data['市町村名_読み'] = ____

# 現状のデータをcsv形式にて保存
df_data.to_csv(path_or_buf='pop202003_version4.csv',index=False)


【関数設定の解説】

 #関数設定 
def get_ja_name(x):

   #ja_nameの箱を作成
      ja_name = ''   

   #xのnum (インデックス)とi(要素)を抜き出す。
      for num,i in enumerate(x):

       #i (要素)が大文字(=True)であれば、
             if(i.isupper()):
           #xのインデックス0 ~numまでをja_nameとする。
                    ja_name = x[0:num]
           #if文終了 (Trueが来た)
                    break;

      #「get_ja_name(x)」という関数にja_nameという値を返す。
      return ja_name

(補足)
リスト[0:num]のとき、0は含まない。
また、[num:]のとき、numは含まない。



③-6.新規columnの作成

カテゴリ―分類して、新規columnを作成する。

# ライブラリのインポート
import pandas as pd

# データの読み込み
df_data = pd.read_csv('pop202003_version4.csv')
 #関数設定 
def chk_city_category(x):
   category = ''
   if('市' in x):
       category = '市'
   elif('町' in x):
       category = '町'
   elif('村' in x):
       category = '村'
   elif('郡' in x):
       category = '郡'
   return category
   
# 新規カテゴリ列の作成
df_data['市町村カテゴリ'] = df_data["市町村名"].map(chk_city_category)

# 不要な行の削除
df_data = df_data.drop([0,1,13])

# 現状のデータをcsv形式にて保存
df_data.to_csv(path_or_buf='pop202003_version5.csv',index=False)

下の仕組みとif文を利用して、関数を作成。

In [2]: test_string = '那覇市'

       # 市が含まれているか判断
       print('市' in test_string)

       # 市が含まれているか判断
       print('県' in test_string)

Out [2]: True
        False 


関数を作るとき以下のような簡単な場合でシミュレーションを行って、正しく機能しているのを確認し、使用する。

In [3]: test_string = '那覇市'

       # 分岐処理関数設定
       def chk_city_category(x):
           category = ''

           if('市' in x):
               category = '市'
           elif('町' in x):
               category = '町'
           elif('村' in x):
               category = '村'
           elif('郡' in x):
               category = '郡'
           return category

       # 市町村カテゴリ判断
       print(chk_city_category(test_string))

Out [3]: 市      

drop関数

 〇列の削除
   ・列名で削除 →drop(”列名”, axis=0)、drop([”列名1”,”列名2”], axis=1)
   ・列番号で削除→drop([num], axis=1)、drop([num1,num2],axis=1)

 〇行の削除
   ・列名で削除 →drop(”行名”, axis=0)、drop([”行名1”,”行名2”], axis=0)
   ・列番号で削除→drop([num], axis=0)、drop([num1,num2],axis=0)
  ※デフォルトがaxis=0なので、なくてもOK。



③-7.データ型の変更と列の並び替え

〇データ型の変更
astype("変更したいカラム名":変更後のデータ型)


〇カラム一覧を取得する
df.columns


〇カラムの変更

df = df[[                       ]]の中身を入れ替えればOK!



③-8.前処理後のデータを使った可視化

# ライブラリのインポート
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# グラフ作画のスタイル変更
plt.style.use('ggplot') 

# 前処理後のデータ読み込み
df_data = pd.read_csv('pop202003_version6.csv')

①ライブラリをインポート

②グラフのスタイル変更(グラフが見やすくなるおまじないと認識でOK)

③データ読み込み


〇データ件数をプロット!

sns.countplot(y=df_data['市町村カテゴリ'])
plt.show()

画像2

件数の可視化を行うことで、どの数が多く、少ないのかが簡単にわかる。


〇データ分布のプロット

sns.stripplot(x="市町村カテゴリ", y="2020-03-01_人口", data=df_data)
plt.show()

画像3


この記事が気に入ったらサポートをしてみませんか?