Windows10でPython3の開発環境と使い方まとめ

# 概要

Windows10でPython3の環境を構築します。生のPythonを入れて必要に応じて様々なライブラリを随時追加していきます。CLIはcmd.exeではなくPowerShellを使います。

# Pythonのインストール

* [Pythonをインストールする（for Windows）](http://qiita.com/taipon_rock/items/f574dd2cddf8851fb02c)
    * この通りで入りました

# pipの設定

何もしなくても入っている

``` shell
> python -m pip --version
================================================
pip 9.0.1 from C:\Users\ftakao2007\AppData\Local\Programs\Python\Python36\lib\site-packages (python 3.6)
================================================
```

# ansibleのインストール(保留中)

**Ansible2.2のPython3.6.1対応はまだされていない可能性があるので。。**

* 事前作業
    * 単純にインストールしようとすると `error: Microsoft Visual C++ 14.0 is required.` と怒られるので [Visual C++ 2015 Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) をインストールしておく
    * pycryptoをインストールしておく
        * pipで単純にpycriptをインストールしようとするとエラーになる
            * [Microsoft Windows Python-3.6 PyCrypto installation error](http://stackoverflow.com/questions/41843266/microsoft-windows-python-3-6-pycrypto-installation-error)

``` shell
### こんなエラー
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(26): error C2061: syntax error: identifier 'intmax_t'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(27): error C2061: syntax error: identifier 'rem'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(27): error C2059: syntax error: ';'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(28): error C2059: syntax error: '}'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(30): error C2061: syntax error: identifier 'imaxdiv_t'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(30): error C2059: syntax error: ';'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(40): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(41): error C2146: syntax error: missing ')' before identifier '_Number'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(41): error C2061: syntax error: identifier '_Number'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(41): error C2059: syntax error: ';'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(42): error C2059: syntax error: ')'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(45): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(46): error C2146: syntax error: missing ')' before identifier '_Numerator'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(46): error C2061: syntax error: identifier '_Numerator'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(46): error C2059: syntax error: ';'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(46): error C2059: syntax error: ','
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(48): error C2059: syntax error: ')'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(50): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(56): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(63): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(69): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(76): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(82): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(89): error C2143: syntax error: missing '{' before '__cdecl'
   C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h(95): error C2143: syntax error: missing '{' before '__cdecl'
   error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe' failed with exit status 2
```

* 対処として一時的に `inttypes.h` を書き換えてインストール後に戻した
    * [Building pycrypto on Windows](http://www.xavierdupre.fr/app/pymyinstall/helpsphinx/blog/2017/2017-01-03_pycrypto.html)

``` shell
### PowerShellの管理者権限でinttypes.hを開いて編集して保存
> notepad 'C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h'
================================================
typedef struct
{
#define intmax_t long long               ### これを追記
#define uintmax_t unsigned long long     ### これを追記
    intmax_t quot;
    intmax_t rem;
} _Lldiv_t;

typedef _Lldiv_t imaxdiv_t;
================================================

### pycryptoのインストール
> python -m pip install pycrypto
================================================
Collecting pycrypto
  Using cached pycrypto-2.6.1.tar.gz
Building wheels for collected packages: pycrypto
  Running setup.py bdist_wheel for pycrypto ... done
  Stored in directory: C:\Users\ftakao2007\AppData\Local\pip\Cache\wheels\80\1f\94\f76e9746864f198eb0e304aeec319159fa41b082f61281ffce
Successfully built pycrypto
Installing collected packages: pycrypto
Successfully installed pycrypto-2.6.1
================================================

### PowerShellの管理者権限でinttypes.hを開いてさっき追記した箇所を削除して保存
> notepad 'C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.h'
================================================
typedef struct
{
    intmax_t quot;
    intmax_t rem;
} _Lldiv_t;

typedef _Lldiv_t imaxdiv_t;
================================================

### ansibleのインストール
> python -m pip install ansible
```

* 事後作業
    * このままだとansibleに実行権限が無く、単にansibleのファイルを開いてしまう動作になる
    * (対応方法確認中...)



# venvの設定

何もしなくても入っている

* [26.9. venv — 仮想環境の作成](http://docs.python.jp/3.3/library/venv.html)
* [pyvenv は deprecated なので venv を使う話](https://jptomo.github.io/blog/2016/01310_not_use_pyvenv_but_venv.html)
    * ` pyvenv` は今後無くなる予定とのこと

* 事前作業
    * [WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する](http://www.atmarkit.co.jp/ait/articles/0805/16/news139.html)
        * これをしてないとPowerShellでActivateするときにエラーになる

``` shell
### 管理者権限でPowerShellを起動し、現在のポリシーを確認
> Get-ExecutionPolicy
================================================
Restricted
================================================

### ポリシーの変更(署名無しでもローカルのスクリプトは実行できるようにする)
> Set-ExecutionPolicy RemoteSigned
================================================
実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (http://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
================================================

> Get-ExecutionPolicy
================================================
RemoteSigned
================================================
```

venv実行テスト

``` shell
### ワークスペースの作成
> python -m venv venvtest

### ワークスペースに移動
> cd venvtest

### アクティベート
> .\Scripts\Activate.ps1
================================================
### 以下のように先頭に(venvtest)がつく
(venvtest) PS C:\Users\ftakao2007\PycharmProjects\python\venv\venvtest>
================================================

### PowerShellではなくcmd.exeの場合は以下
### > Scripts\activate.bat
###

### ディアクティベート
> deactivate

```

# PythonでMySQLに接続するための設定

Ununtu16.04の場合

``` shell
# apt-get install libmysqlclient-dev
# pip install mysqlclient
```

これで `import MySQLdb` ができるようになる

# PythonでMongoDBに接続するための設定

Ununtu16.04の場合

``` shell
# apt-get install pymongo
```

これで `import pymongo` ができるようになる
例

``` python
import pymongo
import pandas as pd
from pymongo import MongoClient
client = MongoClient(host=['192.168.33.11:27017'])
db = client.joruri_plus
collection = db.plus_projects
data = pd.DataFrame(list(collection.find()))
data
```

# Python周りのライブラリのインストール

* IPython
    * Pythonの対話型インタプリタを強力に拡張したもの
        * 拡張された対話型シェル
        * 分離型プロセス間通信モデル
        * 並列コンピューティング機構
* Jupyter
    * IPythonをサーバーで立ち上げてブラウザ上で実行できるようにしたもの
    * 元々がIPython Notebookという名前だった

``` shell
### jupyterのインストール (ipythonも入る)
> python -m pip install jupyter

### jupyterの起動
> jupyter notebook
```

## ruby連携

* [Jupyter連携](http://qiita.com/ftakao2007/items/f232c86df0d561793850#jupyter%E9%80%A3%E6%90%BA)

# 数値計算・機械学習ライブラリのインストール

* NumPy
    * 数値計算を効率的に処理するためのライブラリ
* SciPy
    * 様々な科学計算が実装されたライブラリ
    * 内部でNumPyが使われている
* matplotlib
    * グラフ描画ライブラリ
    * 内部でNumPyが使われている
* pandas
    * Pythonでデータ構造を触ったりデータ分析したりするときに便利なライブラリ
* TendorFlow
    * Googleによって開発されている
    * ディープラーニングを実装するための機械学習ライブラリ
* scikit-learn
    * Googleによって開発されている
    * 機械学習全般のアルゴリズムやデータ処理用関数をカバーしたライブラリ
        * SVM
        * 決定木
        * K-NN
        * K-means
        * 交差検定
        * 回帰分析
        * 主成分析

``` shell
> python -m pip install numpy pandas matplotlib
```

# PyCharmのインストール

* [最強のPython統合開発環境PyCharm](http://qiita.com/yamionp/items/f88d50da8d6b548fc44c)
    * 無償版もあったんですね

# Jupyter Notebook使い方

ウェブDBプレスvol97の伊藤直也さんの記事参考

## Hello World

``` python
def hello():
    return "Hello World"

hello()   ### ここでCtrl+Enter
================================================
'Hello World'
================================================
```

## 図を表示する

* 「%」では始まる命令はマジックコマンド
    * Jupyterへの命令

``` python
%matplotlib inline
import pandas as pd

df = pd.DataFrame([1,2,4,8,16,32,64,128,256])
df.plot()
```

![スクリーンショット 2017-03-26 21.11.23.png](https://qiita-image-store.s3.amazonaws.com/0/20474/e6ac0891-b2a7-5916-3201-b2d1e7890568.png)

``` python
df.describe()
```

![スクリーンショット 2017-03-26 21.12.25.png](https://qiita-image-store.s3.amazonaws.com/0/20474/c4908dc6-e107-ecbd-66f0-0c29aac9ac95.png)

## Markdownと数式のテスト

``` 
# Markdownテスト

## リストテスト

* リスト1
* リスト2

## 数式のテスト

$ \sqrt{x^2 + y^2} $
```

![スクリーンショット 2017-03-26 21.22.20.png](https://qiita-image-store.s3.amazonaws.com/0/20474/eb6b9499-cf1a-4bac-e640-0af78f4a1a24.png)

# pandasの基本

* データ構造
    * Series(シリーズ)
        * 一次元のデータ構造
    * DataFrame(データフレーム)
        * 二次元のデータ構造
    * 階層インデックス
        * より高次元のデータを扱うとき

## データフレームの初期化

``` python
df = pd.DataFrame([1,2,3], columns=['value'])
df
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/f2e8a763-8778-5b95-c5ff-2b57d5ae66d7.png)

タプル(イミュータブルなシーケンス型)のリストを渡す

``` python
pd.DataFrame([('apple',160),('orange',30),('kiwi',80)], columns=['name', 'price'])
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/f4793eaf-e4ab-c12f-1ee2-ac789b3b65a9.png)

ディクショナリ(連想配列、ハッシュみたいなもの)でリストを渡す

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

pd.DataFrame(data)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/bca8a239-b0bb-d3cc-017b-266793f7e087.png)

## 列の追加

値段と注文数を書けた合計金額を出す

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df['total'] = df['order'] * df['price']
df
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/9b8bea28-7c34-f57f-b945-e1c72c3c80b1.png)

## インデックスの指定

``` python
data = {
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data, index=['apple', 'orange', 'kiwi'])
df
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/df75e139-a067-bb56-2f81-e7445796b186.png)

特定の行をシリーズとして取り出し

``` python
data = {
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data, index=['apple', 'orange', 'kiwi'])
df.ix['kiwi']
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/e15c7017-820d-e252-4830-b25d52de448f.png)

## サイズの調査

``` python
data = {
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data, index=['apple', 'orange', 'kiwi'])
df.shape
================================================
(3, 2)
### 3行2列。indexは入らない
================================================
```

## 行や列の選択

fruitの列を選択

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df['fruit']
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/8517747d-eb94-7efc-ed18-0fe9aa200ad9.png)

fruit, orderの2列選択

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df[['fruit','order']]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/b225dae0-8dc2-665b-bcdd-3ce5cefd26ee.png)

head, tail

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.head(2)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/e51203ca-2efc-b312-32e1-8b28a3f791fa.png)


``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.tail(2)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/5de8e309-f18c-c069-d0b5-a071599d9f68.png)

表示範囲をindexで指定

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df[0:2]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/4c563617-7b1b-7dd5-6d59-3a3cee594d34.png)


``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df[1:]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/f78e38fb-9a8f-69fc-be16-eba71fa13c7d.png)


``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.loc[[0,2]]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/aacb6033-db9e-1a4b-9ec6-194de27601af.png)


## サンプリング

実行する毎に抽出される行が変わる

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.sample(n=2)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/587ef4d5-3b9c-0f22-0bfc-70a8a5ad1a2e.png)

## 条件を指定した絞込

SQLのwhere句みたいなもの

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df[df.price > 50]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/382932d7-35c5-c8e3-5bea-0047c94f72a5.png)

Where句を使うと条件にマッチしないものはNaN(Not a number:非数)で埋まる。
pandasでは欠損値として扱われる

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.where(df.price > 50)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/e77d1485-849e-6124-487d-476dbcc04f01.png)

欠損値は削除したり埋めたりできる

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.where(df.price > 50).dropna()
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/e27f1aa4-c97f-5b3d-0f08-ae6b1a701ae8.png)

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.where(df.price > 50).fillna(df.mean())
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/f6788ea9-a40f-736e-663a-f7c4927def21.png)

## 任意の関数の適用

* axis=0 : 行方向
* axis=1 : 列方向
* upper : 大文字にする

``` python
data = {
    'fruit' : ['apple', 'orange', 'kiwi'],
    'price' : [160,30,80],
    'order' : [12,30,8]
}

df = pd.DataFrame(data)
df.apply(lambda x: x.fruit.upper(), axis=1)
```

fruitの列を大文字にする

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/c757e52a-760d-3479-217d-8a2c46cbcdb3.png)

## CSVのソート

CSV読み込み

``` python
df = pd.read_csv('./ruby_1.csv')
df
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/ec8436a1-0521-00b3-7c36-0b27393c3355.png)

Rubyの点数が高い順

``` python
sort_by_ruby = df.sort_values(by='ruby', ascending=False)
sort_by_ruby[['name', 'ruby']]
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/d0ff5c62-9633-4c96-efd8-da88ff2885d3.png)

平均を追加

``` python
df['mean'] = df.mean(axis=1)
df
```

![image](https://qiita-image-store.s3.amazonaws.com/0/20474/d1bd1bfc-90b4-57ef-3d65-6c9cdeb33b26.png)