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

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

**タイタニックのトレインデータをPython３標準モジュールで読込み、加工集計、CSVに出力してみた。**
　**１．TSVデータの読み込み
　２．欠損値をNoneに置換する
　３．CSVに出力する**
##この記事で分かること。##
**<font color="Red">pandas</font>を使わずに、<font color="Red">標準モジュール</font>での**
**・TSVデータを読込みする方法
・欠損値を置換する方法
・CSVへの出力の方法
・例として、<font color="Blue">for</font>文、<font color="Blue">if</font>文、<font color="Blue">dict.get()</font>メソッドを使用したコードの書き方**

##データ概要
**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|

##１．データの読み込み
TSVデータを「**<font color="Blue">with open</font>**」と**<font color="Blue">for</font>**文で空のリスト**list01**に<font color="Blue">**append**</font>する。
（**<font color="Red">import pprint </font>**：アウトプットを要素ごとに改行して見やすくする。）


```python
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**」を**削除する**コードを追加する。
**《使用するメソッド》**
**<font color="Blue">.rstrip('\n')</font>**
末尾の改行を取り除く。「**<font color="Red">'\n'</font>**」が無い場合、改行と空白どちらも削除する。
**<font color="Blue">.split('\t')</font>** 
指定した文字列で区切り、リストをかえす。
今回はタブ区切りなので引数に「**<font color="Red">'\t'</font>**」を入力

```python: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']]
```
##２．欠損値をNoneに置換する
**id47**の**age**と**id64**の**embarked**のデータが存在せず「**''**」と表示されているため、欠損値として「**None**」を置換する。
各要素を**<font color="Blue">for</font>**文と**<font color="Blue">if</font>**文で読込み、「**''**」の場合は「**None**」、それ以外はそのままという条件となる。

**①<font color="Blue">for</font>文と<font color="Blue">if</font>文を使用したやり方**

```python: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]]
```

**②<font color="Blue">for</font>文、<font color="Blue">if</font>文を使わず、<font color="Red">辞書（sub）</font>と<font color="Blue">.get()</font>メソッドを使うやり方。
この場合９行から２行に短縮することが出来る。**

```python:辞書と.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]]
```
##３．CSVに出力する

```python

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で開いてみた**
![qiitalist01none.png](https://qiita-image-store.s3.amazonaws.com/0/340189/79712fe1-21b4-9095-35b4-202f81a12265.png)


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

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