社内勉強会 機械学習入門（5.続Pythonでプログラムを書いてみよう）

今日も、Pythonを使ってプログラムを書いてみたいと思います。
# 題材
PythonでExcelファイルを操作するプログラムです。
Excelファイルを読み、シート上のセル値を標準出力してみます。

以下のようなExcelファイルを「sample.xlsx」というファイル名で準備してください。
ファイルは、「C:\ml-intro」の下に置く前提で進めます。
![2019-08-23_15h11_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/5569f5bb-fb6a-998f-f555-512a0c6a9935.png)

※openpyxlという、PythonでExcelファイルを操作するためのライブラリを使います。

# コードを書いてみよう
Python仮想環境を有効化し、「jupyter notebook」を起動しましょう。
``` 以下のコマンドを実行
$ cd C:\ml-intro
$ env\Scripts\activate.bat
$ jupyter notebook
```

notebookを開いて、ライブラリをインストールしましょう。
``` !pip install openpyxl```


まずは、ファイルを読み、A1セルの値を標準出力してみましょう。

```python
import openpyxl as px

wb = px.load_workbook('./sample.xlsx') # ワークブック読み込み
ws = wb.active                         # ワークシート取得
a1 = ws['A1'].value                    # A1セルの値を取得
print(a1)
```

実行結果は、こんな感じです。（A1セルの値がちゃんと出力されました。）
![2019-08-23_15h20_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/eb99f19f-0b3f-9c46-f517-03d870bf9114.png)

ワークシートを指定したり、R1C1形式でセルの値を取得することもできます。

```python
import openpyxl as px

wb = px.load_workbook('./sample.xlsx') # ワークブック読み込み
# ws = wb.active
ws = wb['Sheet1']                      # シート名を指定
# a1 = ws['A1'].value
r1c1 = ws.cell(row=2, column=1).value  # 2行目、1列目のセルの値を取得
print(r1c1)
```

次は、シート上の「セルの値」をすべて標準出力してみよう。

```python
for row in ws.rows:
    print('----------------------------')
    for c in row:
        print(c.value)
```

ws.rowsは、シート上で"何らかの値や書式設定がされているセル範囲"にある「rowオブジェクト」の集まりです。
サンプルのExcelファイルの場合ですと、4行分のrowオブジェクトが集まったものです。
そのrowオブジェクトの集まりから１つずつfor構文で1行分のrowオブジェクトを取り出しています。
更に、rowは、セルの集まりなので、rowから1つずつcellオブジェクトを取り出して、その値を標準出力しています。

実行結果は、こんな感じです。
![2019-08-23_15h29_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/63794bdd-7774-806e-1364-11dc4616e8a9.png)


# プログラムを改良してみよう
出力結果がイマイチなので、こんな感じ（↓）の標準出力に改修してみましょう。
![2019-08-23_15h46_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/08621fbc-3380-f09b-fb8a-c5364d24944a.png)

```python
import openpyxl as px

wb = px.load_workbook('./sample.xlsx')
ws = wb['Sheet1']
for row in ws.rows:
    row_str = ''
    for cell in row:
        row_str =  row_str + str(cell.value) + '|'
    row_str = row_str[:-1]   # 一番後ろに付いてしまう（|）は削除する
    print(row_str)
```

実行結果は、こんな感じです。
![2019-08-23_15h49_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/edefc71c-2812-c1dc-9b50-4e7c3ee0f2ad.png)

更に、joinメソッドを使って少しコードをスッキリさせてみよう。
joinメソッドは、「組み込み型の１つである str のメソッド」という扱いらしいです。

[参考情報]
・https://python.ms/sub/misc/join/#join-%E3%81%AE%E8%A9%95%E5%88%A4
・https://www.lifewithpython.com/2017/07/why-python-join-is-string-method.html


```python
import openpyxl as px

wb = px.load_workbook('./sample.xlsx')
ws = wb['Sheet1']
for row in ws.rows:
    current_row = []   # 空のリストを準備
    for cell in row:
        current_row.append(str(cell.value)) # リストにセルの値を追加する
    print('|'.join(current_row))            # joinメソッドの引数にリストを渡すと指定文字で連結してくれる
```

実行結果は、こんな感じです。
![2019-08-23_15h49_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/edefc71c-2812-c1dc-9b50-4e7c3ee0f2ad.png)


# 関数を定義してみよう
joinメソッドを使わず、「myjoin」という関数を自作してみよう。

```python
import openpyxl as px

'''
  myjoin関数の定義
    引数：rowオブジェクト
    戻り値：rowに含まれるセルの値をパイプ文字（|）で結合した文字列
'''
def myjoin(row):
    row_str = ''
    for cell in row:
        row_str =  row_str + str(cell.value) + '|'
    return row_str[:-1]

wb = px.load_workbook('./sample.xlsx')
ws = wb['Sheet1']
for row in ws.rows:
    print(myjoin(row))  # myjoin関数を使用
```

実行結果は、こんな感じです。
![2019-08-23_16h19_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101846/5b6c5190-64cc-3aac-9427-58fa9dc1d939.png)


# まとめ

今日は、「繰り返し」や「関数の定義」をポイントにプログラムを書いてみました。
次回は、ようやく機械学習らしいプログラムを書いてみたいと思います。

次回は、「6.手書きの数字を判定してみよう」です。
[社内勉強会 機械学習入門（6.手書きの数字を判定してみよう）](https://qiita.com/masami310/items/01602d8463a0d0fcd787)