【Python3】第1回 タイタニックを標準モジュールだけで集計してみた。 ~データ読込み、None置換、CSV出力編~


概要

かつて、僕は小学生で、おそらく全ての小学生がそうだったように、親とタイタニック観た時気まずかった。

タイタニックのトレインデータをPython3標準モジュールで読込み、加工集計、CSVに出力してみた。
 1.TSVデータの読み込み
 2.欠損値をNoneに置換する
 3.CSVに出力する

この記事で分かること。

pandasを使わずに、標準モジュールでの
・TSVデータを読込みする方法
・欠損値を置換する方法
・CSVへの出力の方法
・例として、for文、if文、dict.get()メソッドを使用したコードの書き方

データ概要

SIGNATE
【練習問題】タイタニックの生存予測
https://signate.jp/competitions/102/data
トレインデータ(tsv)
《データ説明》

カラム ヘッダ名称 データ型 説明
0 id int インデックスとして使用
1 survived boolean 生還結果(1=生還, 0=死亡)
2 pclass int 客室のクラス(1,2,3の順に高級クラス)
3 sex char 性別
4 age int 年齢
5 sibsp int 乗船していた兄弟、配偶者の数
6 parch int 乗船していた両親、子供の数
7 fare float 運賃
8 embarked char 乗船した港(S=Southampton, C=Cherbourg, Q=Queenstown)

《データ一部抜粋》
各要素に一部欠損値有り。
(下記一部抜粋)

id survived pclass sex age sibsp parch fare embarked
3 1 1 female 35 1 0 53.1 S
4 0 3 male 35 0 0 8.05 S
7 0 3 male 2 3 1 21.075 S
47 1 3 female 0 0 7.75 Q
61 1 1 female 38 0 0 80

1.データの読み込み

TSVデータを「with open」とfor文で空のリストlist01appendする。
import pprint :アウトプットを要素ごとに改行して見やすくする。)

import pprint
# 1.TSVデータの読み込み
list01=[]
with open("train.tsv", mode="r") as f:
    for line in f:
        list01.append(line)
pprint.pprint(list01[0:3])

OUTPUT

['id\tsurvived\tpclass\tsex\tage\tsibsp\tparch\tfare\tembarked\n',
 '3\t1\t1\tfemale\t35\t1\t0\t53.1\tS\n',
 '4\t0\t3\tmale\t35\t0\t0\t8.05\tS\n']

appendの際に条件の指定をしなかったので、一つのリストとして、tsvのTAB区切りが「\t」、
末尾の改行が「\n」と表示されている。

このままでは見づらく、集計もしづらいので、先ほどのコードにTAB「\t」と改行「\n」を削除するコードを追加する。
《使用するメソッド》
.rstrip('\n')
末尾の改行を取り除く。「'\n'」が無い場合、改行と空白どちらも削除する。
.split('\t')
指定した文字列で区切り、リストをかえす。
今回はタブ区切りなので引数に「'\t'」を入力

appendの条件に上記メソッドを追加
import pprint
# 1.データの読み込み
list01=[]
# 改行\nとタブ区切り\tを削除する
with open("train.tsv", mode="r") as f:
    for line in f:
        list01.append(line.rstrip('\n').split('\t'))
pprint.pprint(list01[0:3])

OUTPUT 各行をリストとして読み込むことが出来た。

[['id','survived','pclass','sex','age','sibsp','parch','fare','embarked'],
 ['3', '1', '1', 'female', '35', '1', '0', '53.1', 'S'],
 ['4', '0', '3', 'male', '35', '0', '0', '8.05', 'S']]

2.欠損値をNoneに置換する

id47ageid64embarkedのデータが存在せず「''」と表示されているため、欠損値として「None」を置換する。
各要素をfor文とif文で読込み、「''」の場合は「None」、それ以外はそのままという条件となる。

for文とif文を使用したやり方

for文とif文を使い、「''」を「None」に置換する。
list01=[]
list01new=[]
# 1.データの読み込み
# 改行\nとタブ区切り\tを削除する
with open("train.tsv", mode="r") as f:
    for line in f:
        list01.append(line.rstrip('\n').split('\t'))
# 2.欠損値をNoneに置換する
# 「''」の場合は「None」、それ以外はそのままとし、list01newにappendする。
for line in list01:
    new_line=[]
    for value in line:
        if value == '':
            value_after = None
        else:
            value_after = value
        new_line.append(value_after)
    list01new.append(new_line)

pprint.pprint(list01new[0:3])

print('--------' * 10)
none_list = [row for row in list01none if None in row]
pprint.pprint(none_list[7:9])

OUTPUT 全ての「''」が「None」に置換された。

[['id','survived','pclass','sex','age','sibsp','parch','fare','embarked'],
 ['3', '1', '1', 'female', '35', '1', '0', '53.1', 'S'],
 ['4', '0', '3', 'male', '35', '0', '0', '8.05', 'S']]
 --------------------------------------------------------------------------------
[['47', '1', '3', 'female', None, '0', '0', '7.75', 'Q'],
['61', '1', '1', 'female', '38', '0', '0', '80', None]]

for文、if文を使わず、辞書(sub).get()メソッドを使うやり方。
この場合9行から2行に短縮することが出来る。

辞書と.get()メソッドを使用して短縮する場合

import pprint
list01=[]
list01new=[]
with open("train.tsv", mode="r") as f:
    for line in f:
        list01.append(line.rstrip().split('\t'))

# 2.欠損値をNoneに置換する
# 辞書subに「''」を「None」と定義
sub = {'': None}
# 分解した各要素がsubの「''」とTRUEだったらNoneに置換、FALSEだったらそのまま。
list01new = [[sub.get(x, x) for x in inner] for inner in list01]
pprint.pprint(list01new[0:3])

print('--------' * 10)
none_list = [row for row in list01none if None in row]
pprint.pprint(none_list[7:9])

OUTPUT 全ての「''」が「None」に置換された。(先ほどのfor文if文と同じ)

[['id','survived','pclass','sex','age','sibsp','parch','fare','embarked'],
 ['3', '1', '1', 'female', '35', '1', '0', '53.1', 'S'],
 ['4', '0', '3', 'male', '35', '0', '0', '8.05', 'S']]
 --------------------------------------------------------------------------------
[['47', '1', '3', 'female', None, '0', '0', '7.75', 'Q'],
['61', '1', '1', 'female', '38', '0', '0', '80', None]]

3.CSVに出力する


import pprint
list01=[]
list01new=[]
with open("train.tsv", mode="r") as f:
    for line in f:
        list01.append(line.rstrip('\n').split('\t'))

# 辞書型に空白''をNoneと変数subに定義
sub = {'': None}
list01new = [[sub.get(x,x) for x in inner] for inner in list01]

# 3. CSVに出力する
with open(r"list01new.csv", "w") as f:
    for row in list01new:
        print(*row, sep=',', file=f)

OUTPUT Excelで開いてみた

次回 Python3標準モジュールにて、同データの集計加工を行う。

あとがき
セリーヌ・ディオンのセリーヌ・ディオン感は異常。