pythonで定番の単純な集計を行う目的で prast.py を自作しました。
今回はクロス集計を取り上げます。
処理するcsvファイルは前回と同じ data01.csv です。
当Webページで紹介するスクリプトや素材データ一式は、
prast02.zip という圧縮ファイルに同梱しておきます。
Prastクラスに table() というメソッドを設けてあります。
クロス集計を行うものです。
たとえば下のような表を作成します。
賛成 | 反対 | 保留 | |
男性 | 73 | 98 | 30 |
女性 | 78 | 96 | 18 |
これはgender(性別)とopinion(意見)の組み合わせで人数を数え上げたものです。
dod = psx.table("gender", "opinion")
上のように書くと「性別」×「意見」のクロス集計表が得られます。
2つの引数は必須で、それぞれの列ラベルを指定します。
戻り値dod(OrderedDict型)には上記の表の他に
合計欄を付加した度数の表と、2種類のパーセンテージの表が入ります。
つまり4つの表が得られます。
パーセンテージの表は、横方向に足し算をしたときの合計を100%とする表と、
縦方向に足し算をしたときの合計を100%とする表の2種類です。
賛成 | 反対 | 保留 | 合計 | |
男性 | 36.3 | 48.8 | 14.9 | 100.0 |
女性 | 40.6 | 50.0 | 9.4 | 100.0 |
合計 | 38.4 | 49.4 | 12.2 | 100.0 |
賛成 | 反対 | 保留 | 合計 | |
男性 | 48.3 | 50.5 | 62.5 | 51.1 |
女性 | 51.7 | 49.5 | 37.5 | 48.9 |
合計 | 100.0 | 100.0 | 100.0 | 100.0 |
4つのクロス集計表を表示するスクリプトは次のとおり。
変数dod(OrderedDict型)のキーは name, tbl1, tbl2, pct1, pct2 です。
nameは、どの列とどの列のクロス集計かを示すもので
「性別/意見」などの文字列です。
それ以外の tbl1 などは、いずれも DataFrame です。
pct1, pct2 の小数点以下の桁数を2桁にしたいときは
事前に psx.cround = 2
という1行を置きます。
psx.cround = 2
dod = psx.table("gender", "opinion")
先のスクリプトでは欠損値が対象外になっています。
欠損値も数え上げるのであれば下のように事前に fillna() を呼び出します。
psx.fillna()
dod = psx.table("gender", "opinion")
欠損値も数え上げ、出力をcsvファイルにするスクリプトを掲げておきます。
1# table02.py (coding: cp932) 2import os 3import pandas as pd 4from prast import Prast 5 6dtf = pd.read_csv("data01.csv") 7psx = Prast(dtf, "data01_c.txt", "data01_i.txt", "cp932") 8psx.fillna() # object型の列の欠損値に名前付け 9dod = psx.table("gender", "opinion") 10name = dod.pop('name') 11out_file = "table02.csv" 12if os.path.exists(out_file): # out_fileが存在するなら削除 13 os.remove(out_file) 14with open(out_file, "a") as f: 15 f.write(name + "\n") 16 for key in dod.keys(): 17 dod[key].to_csv(f, encoding="cp932") 18 f.write("\n") # 区切りとして空白行を書き込む
度数とパーセンテージを一つにまとめて
各セルを「度数(パーセンテージ)」の形式にしたいことがあります。
73(36.3)
のようにパーセンテージを括弧に入れて付加する形です。
table() で度数の表とパーセンテージの表が得られるので
2つの表の対応する各セルを結合すればいいことになります。
賛成 | 反対 | 保留 | 合計 | |
男性 | 73(36.3) | 98(48.8) | 30(14.9) | 201(100.0) |
女性 | 78(40.6) | 96(50.0) | 18(9.4) | 192(100.0) |
合計 | 151(38.4) | 194(49.4) | 48(12.2) | 393(100.0) |
この結合のためのメソッド join_table() を設けてあります。
ただ、これは Prastクラスのメンバーメソッドではありません。
prast.py の中で一般的なメソッドとして定義してあります。
dtf = join_table(dtf1, dtf2, fmt="%s(%s)")
戻り値は結合した結果(DataFrame)です。
第1引数と第2引数は、結合の材料となる DataFrame 。
第3引数の fmt は、セルの書式を指定するものです。
%記法の書式(他言語のsprintfと同じ)で指定します。
省略すると "%s(%s)"
になります。
サンプルのスクリプトは下のとおり。
書式を "%d(%5.1f)"
としているので
小数点の位置がそろうのではないかとおもいます。
Prastクラスに属していない join_table() を呼び出す関係で
今回は import prast as ps
としました。
そうしておけば ps.join_table()
として呼び出すことができます。
〜 以上 〜
Copyright (C) T. Yoshiizumi, 2018 All rights reserved.