コード規約、メソッド対応表


<!-- memo20200719コメントはすべてコードの中にコメントアウトで書く、本文中には書かない-->
<!--参考文献、ねこSQL、前処理大全、緑本、時系列、Pythonベイズ-->

# title_コード規約_各言語ごとのルール

## chapter_python

### 使用するライブラリまとめ

``` py
import pandas as pd
import matplotlib.pyplot as plt

import numpy as np

import os
import glob
import shutil

import datetime
from dateutil.relativedelta import relativedelta

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', 100)
```

### python_コード規約

``` python
df_used_method1_used_method2\
= df.copy()\
    .used_method1()\
    .used_method2()\

#for文のネストは2階まで
#それ以上必要な場合は、リスト内包表記などで表す
```

### .pyファイルの書き方

``` python
#1.関数自体の説明
"""ここに説明を書く"""

#2.ライブラリのimport
import pandas as pd

#3.変数の指定
START_DATE = 20200527

#4.main()の中で使用する関数の定義
def func1(parameter1:str) -> pd.DataFrame:

#5.main()の定義
def main()

#6.
if __name__ == "main":
    main()
```

### pythonからsqlを動かす

``` python
import cufflinks
import sqlalchemy

%load_ext sql
%sql postgres://~
cufflinks.go_offline()

#1.jupyter上で動かす
%%sql
select * from mart;

#2.sql_alchemyを使う
pd.read_sql('select * from mart.table', con = sqlalchemy.create_engine('postgres://~'))

#3
pd.read_csv('select * from mart.table', con = sqlalchemy.create_engine('postgres://~'))
```

#### pythonのデータをsqlにはき出す

``` python
df_base.to_sql(
    name = 'table_name',
    con = sqlalchemy.create_engine('postgres://~'),
    schema = 'schema_name',
    if_exists = 'append',
    index = False
)
```

### jupyter_notebookをhtmlで保存

``` python
os.system('jupyter nbconvert --to html ipynb_filename.ipynb')
                   
```


### argparseの書き方

``` python
#main()の中で引数をとる時に必要みたい
import argparse

START_DATE = 20200529

def main():
    parser = argparse.ArgumentParser()
    #.pyファイルの外で指定する場合
    parser.add_argument("--parameter1", help="parameter1の説明", required=True)
    #.pyファイルの中で、変数を指定する場合
    parser.add_argument("--parameter2", help="parameter2の説明", default=START_DATE, type=int)
    args = parser.parse_args()

    pd.read_csv('args.parameter1')
    start_date = args.parameter2

# help = '~': 引数の説明、なくてもいい
# parser.add_argument('-param', '--parameter'): 一個目の'-(~)'はなくてもいい、コマンドで打ち込むときに変数名を全部打つのが大変だから、コマンドでは-~でうって、pyスクリプトのなかでは--~の変数名を使う
# parser.add_argument('param') 必須の情報
# parser.add_argument('--param', action = 'store_true') フラグ変数、shで引数を取るわけではない、--paramが書かれていればTrue,いなければFalseが返る
# parser.add_argument('--param', required = 'True') 必須変数の指定、ないとエラー
# parser.add_argument('--param', nargs = '+') 複数個の引数をリスト形式で取得、記述はスペースを入れて書いてく
```

### loggingの書き方

``` python
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
sh=StreamHandler()
logger.addHandler(sh)

logger.info("parameter1: {}".format(args.parameter1))

#1.basicConfigで一括して記述
logging.BasicConfig()
#簡単ではあるが、細かい設定は出来ない

#作成したスクリプトで、デフォルトでエラーが返るような設計はしない
#print文か、loggerでメッセージを表示
```


``` python
#1.レベル設定
logger.setLevel(logging.DEBUG)
#DEBUG-INFO-WARN-ERROR、の4段階

#2.Handlerの設定
logger.addHandler(StreamHandler())
#StreamHandler()と、FileHandler()の2種類がある
```

### tqdmライブラリ_実行の状況を可視化

``` python
from tqdm import tqdm
for i in tqdm(list_a):
    print(i)
```

### assert句_処理を止める

``` python
assert True/False, 'エラーメッセージ(手打ち)'
```

### try/except_エラーでも処理を止めない

``` python
try: 
    実行するコード
except:
    上記のコードがエラーの場合のコード
```

### warningsライブラリ_処理が止まらないエラーを無視する

``` python
import warnings
warnings.filterwarnings('ignore')
```

## chapter_sql

### sql_コード規約

``` sql
--sql
select
    datamart1.column1
    , datamart1.column2
    , datamart2.column3
from
    datamart1
        left join
    datamart2
        on = column2
where
    datamart1.column1 > 10
;

select
    column1
    , column2
    , sum(column3)
    , avg(column4)
from
    datamart1
group by
    column1
    , column2
;
```
+ すべて、小文字
+ インデントは上記のとおり




## chapter_sh

### コマンド一覧

#雑記_オプション
``` sh
#オプションには、引数を取るものと取らないものがある #-lリスト?、何かを一覧で表示するみたい

#-w         1アルファベットの場合
#--width    ロングオプションの場合

#-i         処理の実行前にy/nで確認させることがある
#-i         大文字小文字を区別しないときに使われる、--ignore-case

#--help     コマンドの使い方を説明
#同様の操作を行うのに、manコマンドがある、例、man cat
#例、cat --help

#-q         quiet:正常に終了したら0、それ以外の場合は0以外を返す
```

#雑記_コマンド
``` sh
date

pwd #カレントディレクトリを表示する

cd  #カレントディレクトリを変更する
cd ~ #ホームディレクトリに戻る

curlコマンド
「curl」コマンドは、さまざまなプロトコルに対応したデータを転送するためのコマンドです。
意味、see_URL
-i: Response HeaderとBodyを出力
-H: Request Headerを追加
#curl コマンド 使い方メモ
#https://qiita.com/yasuhiroki/items/a569d3371a66e365316f
#<!--「curl」コマンドは、さまざまなプロトコルに対応したデータを転送するためのコマンドです。 https://www.atmarkit.co.jp/ait/articles/1606/22/news030.html-->

alias エイリアス名='コマンド'
#例、alias ll='ls -l'

#不要なスペースを入れてはいけない
#×、param_str = 'something'

#プロンプトの内容を変更する
PS1='変更したい文字列'

ps #プロセスを表示
jobs #ジョブを表示
fg #フォアグラウンドへ
bg #バクグラウンドへ

kill プロセス番号 #プロセスの終了
kill %ジョブ番号  #ジョブの終了

#標準出力などが長い場合に、less形式で表示させる
ls | less

#フィルタコマンド:標準入力を入力として受け取り標準出力に出力するコマンド
#代表的なフィルタコマンド
cat
head
tail
grep
sort
uniq
tac
wc
```

### lsした時の青い文字が読めないからピンク色にする

`` sh
export LS_COLORS='di=01;35'
#ls でディレクトリの青色文字を見やすくする https://qiita.com/hikoma/items/277fc7b4a1e4ae86137b
``

### ログアウト

``` sh
exit
#exitコマンドによってシェルの終了とログアウトが同時に行われるため、logoutコマンドは使わずexitで統一するのがいい
```

### シャットダウン

``` sh
#シャットダウンはめったに行うことのない作業
shutdown -h now
#上記は電源を断つ場合、再起動は-rと書き換える
```



### aliasの追加

``` sh
#sh
alias name_alias='コマンド'
#ex. alias ls='ls -F'
#イコールの前後に空白は入れない
#あるコマンドがaliasかどうかの判断をするときは、type コマンド、と入力すればよい
#aliasではない状態で実行する場合は、コマンドの前に、command または、\ を追加し、実行する
```


### 権限

いま、rootユーザで作業しているのか、、、
権限の関係で、危険な作業が出来たりしたらやばくね

#### rootユーザのパスワード変更

``` sh
sudo passwd root
```

### ライブラリ

#### ライブラリ_インストール_python

``` sh
pip install ライブラリ名
```

#### ライブラリ_アップデート

``` sh
pip install -U ライブラリ名
```

#### ライブラリ_shell_インストール

``` sh
apt-get install ライブラリ

#例、apt-get install mlocate
```

### 環境変数の追加方法

``` sh
export シェル変数名
```

# title_メソッド対応表_データ分析関連

## chapter_データ_テーブルデータのデータ理解/データ準備

### 1.値に対する操作

#### str_文字列を特定の記号で分割

``` python
#リスト形式で取得
str_data.split('特定の文字列')
```

#### str_文字列の末尾n字を抽出

``` python
str_data[-n]
```

#### str_文字列の末尾n字を削除

``` python
str_data[:-n]
```

#### str_テキストデータが特定の文字列を含むかのチェック

``` python
str_data.find('探す文字列')
#文字列が含まれれば"1"、含まれなければ"-1"
```

#### str_変数に応じて内容を変更

``` py
param_a = 'a'
param_b = 'b'

'%s %s' % (param_a, param_b)
'{} {}'.format(param_a, param_b)
f'{param_a} {param_b}'
```

#### str_値の内容を表示

``` py
print(str)
```

``` sh
echo $str
#変数をよぶ場合は、$、が必要
```

#### str_複数の要素を結合し文字列にする

``` py
"".join(list_tmp)
#結合する文字列の間に何かを入れる場合はクオテーションの中に入れる
"_".join(list_tmp)
#例、文字列の間にアンダーバーを入れる
```

#### float_距離

``` py
math.sprt(x**2, y**2)
```

#### float_角度

``` py
#ラディアン
#yが先に来る
math.atan2(y, x)
#360°
math.degrees(math.atan2(y, x))
```

### 2.リストに対する操作

#### listを結合

``` python:python
list1 + list2
```

#### リスト内包表記

``` python:python
[i for i in range(100)]

#if文を使う場合
[i for i in range(100) if i > 50]
```

#### 辞書型の要素の取得

``` python:python
dict_tmp.get(key, None)
#辞書型の場合、要素に対応するものが無いとエラーがかえるため、上記の処理を行う
dict_tmp['key']
dict_tmp.key
```

#### 辞書型の要素の更新

``` python:python
dict[key] = new_value
```


#### lambdaとapply()で処理を行う

``` python:python
df.new_column\
     = df.column.apply(lambda x: str(x)[3:6])
```

#### nullの補充

``` python:python
df_tmp.column1.fillna('some_value')
```

#### nullの補充_バックフィル、フォワードフィル

``` py
df_tmp.column1.fillna(method = 'ffill') # 'bfill'
```

#### pd.seriesをdfに変換

``` python
series.to_frame()
#name='column_name'を引数にとることで、カラム名を変更できる
```

<!-- 演算 -->

#### 演算をする

``` python
#python
#平均
np.average(nparray, axis = n)
#2次元以上のデータの場合、平均の次元によって結果が異なる

np.array().mean()

#割り算
np.array(nparray1, nparray2)
```

### 3.テーブルに対する操作

<!--
検証
抽出(query, loc)
複数マート(concat, join)
変換
表示(head, display)
集約(groupby)
ウィンドウ関数
-->

#### 検証_キーでユニークになるか

``` python
#python

```

``` sql
--sql

```

#### 検証_レコードに重複が無いか

``` python
#python

```

``` sql
--sql

```

#### 検証_行数のカウント

``` python
#python
len(df)
```

``` sql
--sql
select
    count(*)
from
    datamart1
;
```

#### 検証_テーブルデータのサイズ確認

``` python
#np.array
#形状のチェック
np.array().shape
#shapeの結果を変数化する
dimension3, dimension2, dimension1 = dimension_3_np_array.shape

#pd.DataFrame
df_tmp.shape
```


#### 検証_nullをdf全体でチェック

``` py
df_base.isnull().any()

#df_base全体でnullが一つもないことを確認
df_base.isnull().any().any()

#以下のコードは間違い、十分気を付けること
#df_base.any().isnull()
```

#### 検証_dfがからかどうかを判定

``` python
df_base.empty()
```

#### 抽出_列の抽出

``` python
#データフレーム形式で抽出
df.loc[:,['column']] #df.loc[:,['column1','column2']]
df[['column']]       #df[['column1','column2']]
df.iloc[:,n:m]

#シリーズ形式で抽出
df.loc[:,'column']
df['column'] #行にも列にも使える
df.column

#locの使い方
#loc[条件_行,条件_列]で指定するのは、それぞれ行の長さのTrue/Falseリスト、列の長さのTrue/Falseリスト
```

``` sql
--sql
select
    column1
from
    datamart
;

select
    *
from
    datamart
;
```

#### 抽出_行の抽出

``` python
df.loc[n:m]
```

#### 抽出_条件に一致する列の抽出

``` py
df_tmp.loc[:,df_tmp.loc[5]==10]
#一行の中に.loc[]が2つ含まれる
```

#### 抽出_条件に一致する行を抽出

``` python
#一つの条件で行う
df_tmp.query('column1 == 10')
df_tmp.loc[df_tmp['column1'] == 10]
#カラム名に空白が入る場合、query()は使えないが、.locは使える
df_tmp.loc[df_tmp["column_a"].isin(list_tmp)]
#特定の値に該当する場合のみ抽出
#別の方法、df_tmp.loc[df_tmp.column1 == 10]
#別の方法、df_tmp[df_tmp.column1 == 10]

#複数条件で行う
df_tmp\
    .query('column1 == 10')\
    .query('column2 >= 20')
df_tmp.query('column1 == 10 & column2 >= 20')
df_tmp.loc[(df_tmp["column1"] == 10)&(df_tmp["column2"] >= 20)]
#別の方法、df_tmp.loc[(df_tmp.column1 == 10) & (df_tmp.column2 >= 20)]
#別の方法、df_tmp[(df_tmp.column1 == 10) & (df_tmp.column2 >= 20)]
```

``` sql
--sql
select
    column1
from
    datamart1
where
    column1 == 10
;

select
    column1
    , count(column1)
from
    datamart1
group by
    column1
having
    count(column1) == 10
;
```

#### 抽出_先頭の行の抽出

``` python
#python
df.head(10)
```

``` sql
--sql
select top(10)
    column1
from
    datamart
;

select
    column1
from
    datamart
limit
    10
;
```


#### 抽出_重複なく列を抽出

``` python
set(df.column1)
```

#### 抽出_重複なく行を抽出

``` py
#python

df_tmp.drop_duplicates()
df_tmp.unique()
df_tmp[df_tmp.duplicated()]
```

``` sql
--sql
select unique
    *
from
    datamart
;
```

``` sh
sort filename.txt | uniq

#別の方法
sort -u filename.txt
```

#### 抽出_nullを含む行を抽出する

``` python
df_tmp.loc[df_tmp['column'].isnull()] 
```

#### 抽出_nullを含む行を除外する

``` python
df_tmp.loc[~df_tmp['column'].isnull()] 

df_tmp.dropna(subset=['column'])
```

#### 複数マート_JOIN

``` python
#python
pd.merge(
    df1,
    df2,
    on = ['column1','column2'],
    how = 'left')

pd.merge(
    df1,
    df2,
    left_on  = ['column1','column2'],
    right_on = ['column3','column4'],
    how = 'left')

df1.merge(
    df2,
    on = 'column1',
    how = 'left')
```

``` sql
--sql
select
    datamart1.column1
    , datamart1.column2
    , datamart2.column3
from
    datamart1
        left join
    datamart2
        on = column2
```

#### 複数マート_JOIN_カラム名を変更

``` py
pd.merge(
    df1
    , df2
    , on = 
    , how = 
    , suffixes = ['_left', '_right']
)
```

``` py
df1_suffix = df1.add_suffix('_')
df2_suffix = df2.add_suffix('_')
# add_prefixもあるよ

pd.merge(
    df1_suffix
    , df2_suffix
    , left_on = 
    , right_on = 
    , how = 
)
```

#### 複数マート_CONCAT

``` python
#python_numpy
#縦
np.concatenate([nparray1,nparray2], axis=0)

#横
np.concatenate([nparray1,nparray2], axis=1)
```

``` python
#python_pandas
#縦
pd.concat([df1,df2],axis=0)

df1.append(df2)

#横
pd.concat([df1,df2],axis=1)
```

``` sql
--sql
select
    column1
from
    datamart1
union -- union all / intersect / except
select
    column2
from
    datamart2
```

#### 複数マート_CONCAT_for文で生成されたマートの結合

``` py
df_base = pd.DataFrame()
for i in ~:
    df_base = pd,concat([df_base, df_tmp])
```

``` py
list_df = list()
for i in ~:
    list_df.append(df_base)
df_base = pd.concat(list_df)
```

``` python
for i_enumerate, i in ~:
    
    if i_enumerate == 0:
        df_base = df_tmp
    else:
        df_base = pd,concat([df_base, df_tmp])
```


#### 変換_並び変え

``` python
#python
df.sort_values(column_name, ascending = True/False)
```

``` sql
--sql
select
    *
from
    datamart1
order by
    column1
```

``` sh
sort input

#数字で並び替える
sort -n input

#逆順で並び替える
sort -r input
```

#### 変換_データ型変換

``` py
#df読み込み前
pd.read_csv(path_data, dtype = {'columns': 'object'})

#df読み込み後
df_tmp.astype(float)
```

#### 変換_データを生成する

``` python
#python
#すべて同じ値のnparrayを生成
#例、3次元
np.tile(数字, (n, n, n))
```

``` sql:sql
drop table if exists schema.datamart;
create table schema.datamart as (select ~ )
```

#### 変換_カラムの追加

``` python
#python
df_tmp.assign(column = 10)

df['column'] = 10
```

``` sql
--sql
select
    10 as column1
from
    dataframe
;
```


#### 変換_カラム名の変更

``` python
#python
df.rename(columns = {'column1':'new_column1','column2':'new_column2'})

pd.DataFrame(df.values, columns = ['new_column1','new_column2'])

df.columns = ['new_column1','new_column2']

df.columns = 'new_' + df.columns

pd.read_csv(path_data, index_col = list_tmp) #カラムの数字は可
```

``` sql
--sql
select
    column1 as new_column1
from
    datamart1
;
```

#### 変換_カテゴリデータをモデリング用に変換

``` python
import category_encoders as ce

list_column_ohe = ['column']
ohe = ce.OneHotEncoder(cols = list_column_ohe, handle_unknown = 'impute')
#handle_unknownが何をしているのかは、わからない

#OneHotEncoderオブジェクトに、データ変換の形式を記憶させる
ohe.fit(x_train)

#記憶させたデータ変換の形式に従って、データを変換する
ohe.transform(x_train)
ohe.transform(x_test)

#ohe.fit_transform()を使えば、データ変換の形式を記憶とデータの変換を一度に行うことができる

#参考_Category Encodersでカテゴリ特徴量をストレスなく変換する
#https://qiita.com/Hyperion13fleet/items/afa49a84bd5db65ffc31
```

#### 変換_dfのn行目をdrop

``` python
df_tmp.drop(df_tmp.index[0])
```

#### 変換_相関行列の取得

``` py
df_base.corr()
```

#### 変換_クロス集計の作成

``` py
pd.crosstab(df_base["column1"],df_base["column2"])
```

#### 表示_display

``` python:python
display(df_tmp)
```

#### 表示_displayで省略されずに表示するようにする

``` python:python
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', 100)
```

<!--集約-->

#### 集約_基本

``` python
#python
df_base\
    .groupby(['column1','column2'])\
    .agg({'column3':'sum',
          'column4':'mean'})\
    .reset_index()
```

``` sql
-- sql
select
    column1
    , column2
    , sum(column3)
    , avg(column4)
from
    datamart1
group by
    column1
    , column2
;
```

#### 集約_特定の要素だけをカウント

``` python
df_tmp\
    .groupby('column1')\
    .agg({'column2':'nunique'})
```

``` sh
sort filename | uniq -c 

#並び替えをする場合
sort filename | uniq -c | sort -n 
```

#### 集約_1つのカラムに対して複数の演算を行う

``` python
df_tmp\
    .groupby('column1')\
    .agg({'column2':['sum', 'min', 'max']})
```

#### 集約_groupbyで抽出した後のdfに対して処理を行う

``` py
def func_rmse(df_base):
    tmp = (df_base["target"] - df_base["predict"])**2
    return pd.Series({"RMSE" : sqrt( sum(tmp)/len(tmp) )})

df_base\
    .groupby(["column1", "column2"])\ #"column1", "column2"はtarget,predictではない
    .apply(func_rmse)
```

<!-- ウィンドウ関数 -->

#### 集約_クロス集計

``` python
df_pivot_table\
    = pd.pivot_table(df_employees
                   ,values='EMPLOYEEID'
                   ,index='HIREFISCALYEAR'
                   ,columns='BLOODTYPE'
                   ,aggfunc='count')\
        .fillna(0.0)

df_pivot_table

#メモ:pd.crosstab()では、もっといろいろクロス集計できるみたい
```

#### ウィンドウ関数_基本

``` python
#python

```

``` sql
--sql

```

#### ウィンドウ関数_縦方向にデータをずらす

``` python
#python
#n行、下に下げる
df_tmp.shift(n)
```

<!-- モデリング用のデータ分割 -->



## chapter_データ_時系列データの処理

#### 時系列マート_分割

``` python
from sklearn.model_selection import TimeSeriesSplit
TimeSeriesSplit(n_splits = 3).split(x_train, y_train)
```

#### 日時データ_文字型→時間型

``` python
datetime.datetime.strptime('2020-05-24', '%Y-%m-%d')
# %Y%m%d: yyyymmdd
# %y%m%d: yymmdd
```

``` py
#yyyymmdd形式(int)を、datetime型に変換
pd.to_datetime(df_tmp.loc[:, ['column_yyyymmdd']].astype(str))
```

``` py
#param_dateは、リストでも、一つの値でもOK
pd.to_dataframe(param_date)
```

#### 日時データ_時間型→文字型

``` python
datetime.datetime.strftime(date_datetime, '%Y-%m-%d')
date_datetime.datetime.datetime.strftime('%Y-%m-%d')
```

#### 日時データの差分

``` python
date_datetime + datetime.timedelta(days=7)
date_datetime + relativedelta(weeks = 1)
```

#### 日時データ_曜日の情報

``` python
datetime.weekday(date_datetime)
```

#### 日時データ_今日の日付を取得

``` python:python
datetime.datetime.today()
```

#### 経過時間のカウント

``` python
#週の経過時間をカウント
(datetime1 - datetime2)/np.timedelta64(1,'W')
```

#### カレンダー_日本の祝日_チェック

``` python
import jpholiday
datetime_data.jpholiday.is_holiday
#True/Falseで返る
```

#### カレンダー_日本の祝日_名前を取得

``` python
datetime_data.jpholiday.is_holiday_name
#datetime_dataが祝日であれば祝日名、祝日でなければNoneが返る
```


## chapter_データ_画像データの処理

#### 画像データの読み込み

``` python
#python
import cv2
cv2.imread('filename.png')

import PIL
PIL.image.open('filename.png')
```

#### 画像データの表示

``` python
#matplotlib：np.array形式
plt.imshow(np.array(PIL.image.open('filename.png')), cmap='gray', vmin=0, vmax=65535)

#cv2
cv2.imshow("image_name", cv2.imread('filename.png'))
#"image_name"は任意で設定

#PIL
PIL.image.open('filename.png').show()
```

#### 画像データの変換

``` python
#python
#画像データのnp化
image = PIL.image.open('filename.png')
np.array(image)
```

#### 画像の一部の抽出

``` python
#python
np.array(PIL.image.open('filename.png'))[上ピクセル:下ピクセル, 左ピクセル:右ピクセル]

np.copy(np.array(PIL.Image.open(photo_name.png)), (上ピクセル:下ピクセル, 左ピクセル:右ピクセル))
```

#### 画像に書き加える

``` python
#python

#四角を書き加える
cv2.rectangle(np.array(image), (右ピクセル, 上ピクセル), (左ピクセル, 下ピクセル), (255, 255, 255), 4)
plt.imshow(np.array(image),cmap='gray',vmin=0,vmax=65555)
```

#### 画像の変換：convolve2d

``` python
#Pythonのconvolve2dについて https://ja.stackoverflow.com/questions/22363/pythonのconvolve2dについて
from scipy import signal
parameter_convolution = 3
signal.convolve2d(np.array(PIL.Image.open(photo_name.png)), parameter_convolution , mode='valid')
```

#### TIF形式の対応

``` pyhton
#最後の数字で、何番目の画像を抽出するのかを変える
Image.open('~.tif').seek(0)
```

## chapter_可視化の処理_matplotlib

### 作画全体について

<!-- ・text_axを作成 ・2軸(ax.twinx()) ・凡例の場所を調整-->

#### Artistオブジェクト_階層

``` 
fig
    axes
        #リスト
        lines
        texts
        images
        
        #軸
        xaxis
        yaxis
        
        #便利メソッド
        plot
        hist
        scatter

#早く知っておきたかったmatplotlibの基礎知識、あるいは見た目の調整が捗るArtistの話 https://qiita.com/skotaro/items/08dc0b8c5704c94eafb9
#matplotlib_tutorials https://matplotlib.org/tutorials/index.html
```

#### plt_figオブジェクトの作成

``` py
plt.figure(
    figsize=(6,4) #表示する画像のサイズを指定
    , dpi=200 #値が大きいと画質がいい
)

#figsizeの縦横を2倍にすると表示される画像のサイズも2倍になる。

#dpiで解析度を指定。dpiを2倍にすると画像サイズは2~3倍程になる(正確に何倍になるわけではない)、またmspaint.exeで開いたファイルを目視で確認すると縦横の長さはちょうど2倍になったように見える。
```

#### plt_フォントサイズの変更

``` py
plt.rcParams["font.size"]=9
```

#### plt_ラベルのフォントサイズを更新

``` python
plt.tick_params(fontsize = 16)
```

#### plt_matlab型をobject_oriented型に変換

``` python
fig = plt.gcf() ## Get Current Figure
ax  = plt.gca() ## Get Current Axes

#可視化の種類：MATLAB型とobject_oriented型
#ここで紹介したのは、MATLAB型→object_oriented型
```

#### plt_複数画像の表示_軸の範囲をそろえる

``` python
plt.subplot(行, 列, 
            sharex = 'all', #横軸の座標が、すべての図で一致する
            sharey = 'all', #縦軸の座標が、すべての図で一致する
)

#allではなく、colかrowを指定することで、可視化の範囲を、列単位、行単位でそろえることができる
#.set_ylim()で一つの図形の範囲を指定すれば、その設定が他のすべての図形の範囲に適応される
```

#### plt_複数画像の表示_figオブジェクト、axオブジェクトの作成

``` python
#memo20210126:返り値が2つあるので個人的には非推奨
fig, ax = plt.subplots(縦, 横, figsize=(6,4)) 
#fig、は使わない
ax[1].plot(~)
```

#### plt_複数画像の表示_matlab型

``` python
plt.subplot(縦, 横, 1)
plt.plot(~)
plt.subplot(縦, 横, 2)
plt.plot(~)
```


#### fig_複数画像の表示_axオブジェクトの作成

``` python
fig = plt.figure()
ax = fig.add_subplot(縦, 横, 1)
ax = plot(~)
ax = fig.add_subplot(縦, 横, 2)
ax = plot(~)
```

#### fig_複数画像の表示_複数のサブプロットが画面内に収まるようにする

``` py
#object oriented
fig.tight_layout()

#調整にfig.suptitle("~")までは考慮されないため、axとfig.suptitleが重なる問題が生じる。
#解決として、調整後のfigを表示する範囲を指定する。
fig.tight_layout(rect=[0,0,1,0.95])
#一番最後の要素が上であり、95%地点から描画を始めるという意味
#参考:matplotlibでsuptitleを考慮してtight_layoutする https://tm23forest.com/contents/matplotlib-tightlayout-with-figure-suptitle


#matlab
plt.tight_layout()
```

#### fig_複数画像の表示_プロットの上下左右の空白を指定

``` python
#引数は、0.0~1.0
#object_oriented
fig.subplots_adjust(left=0.3)

#matlab
plt.subplots_adjust(wspace = 0.4, hspace = 0.6)
```

#### fig_複数画像の表示_axオブジェクトを任意の位置に作成

``` py
#リスト内の値は0.0~1.0
ax=fig.add_axes([左、下、右、上])
```

#### fig_グラフにタイトルをつける

``` py
fig.suptitle("~")
```

#### fig_図中にテキストの表示

``` py
fig.text(x, y, str)

#xとyは0~1のfloatでそれぞれ横軸縦軸における配置場所を示す。
#ページ番号の入力でよく使われる。
```

#### fig_ラベルが自動で重ならないようにする

``` python
fig.autofmt_xdate()
```

#### fig_時間の軸が重なる時、重ならないように調整

``` python
fig.autofmt_xdate()
```

#### fig_背景を透明にする

``` python
#引数は、0.0~1.0
#0.0で透明
fig.patch.set_alpha(0.0)

#特定のaxの透明度を調整することも可能
ax.patch.set_alpha(0.3)
```

#### fig_オブジェクトのクリア

``` python
fig.clear()
```

#### fig_3d_plotの作成

``` py
fig.add_subplot(111, projection='3d')
#参考: mplot3d tutorial https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
```

#### ax_グラフにタイトルをつける

``` python
#object_oriented
ax.set_title('title')

#matlab
plt.title('title')
```

#### ax_ラベル_軸のラベルをつける

``` python
#object_oriented
ax.set_xlabel('xlabel_name')
ax.set_ylabel('ylabel_name')

#フォントサイズの変更
ax.set_xlabel('xlabel_name', fontsize=12)

#matlab
plt.xlabel('xlabel_name')
plt.ylabel('ylabel_name')
```

#### ax_ラベル_軸のラベル調整

``` py
ax.set_xticklabels(
    list #ラベル名の書かれたリスト
    , rotation=45 #斜めに回転
    , ha='right' #今後調べる
)
```

#### ax_凡例_表示

``` python
#object_oriented
ax.legend()
#ax.plot(~, label='~')を先に書いておく

#matlab
plt.legend('~')
#2段以上で書く時には、リスト形式で渡す
```

#### ax_凡例プロットにラベルを付け自動生成する

``` py
ax.~(~, label = 'a')
ax.~(~, label = 'a')
ax.~(~, label = 'a')

ax.legend()
```

#### ax_表示するグラフの範囲の指定

``` python
#object_oriented
ax.set_xlim([右, 左])
ax.set_ylim([上, 下])

#matlab
plt.xlim([右, 左])
plt.ylim([上, 下])
```

#### ax_表示する画像を正方形にする

``` python
#python
aspect = (ax.get_x_lim()[1] - ax.get_xlim()[1]) / (ax.get_y_lim()[1] - ax.get_y_lim()[0])
ax.set_aspect(aspect)
```

#### ax_グリッド線の対応

``` python
#object_oriented
ax.gr
id()

#matlab
plt.grid()
#グリッド線を表示させない
plt.grid(False)
```

#### ax_縦線の表示

``` python
ax.vlines(横軸の座標, 縦線の下側:int, 縦線の上側:int, '色':str)

ax.axvline(横軸の座標)
```

#### ax_横線の表示

``` py
#object_oriented
ax.axhline(y=高さ)
```

#### ax_特定の範囲に色付け

``` py
ax.fill_between(横軸_リスト形式, 縦軸_リスト形式)
```

#### ax_図中にテキストの表示

``` python
#object_oriented
ax.text(横軸の座標:int, 縦軸の座標:int, '文書の内容':str)
```

#### ax_軸の調整_区切りの数を変更

``` py
#object_oriented
ax.locator_params(axis = 'x', nbins = 5)
ax.locator_params(axis = 'y', nbins = 5)

#matlab
plt.locator_params(axis = 'x', nbins = 5)
plt.locator_params(axis = 'y', nbins = 5)
```


#### ax_軸の調整_時間の幅の調整

``` python
import matplotlib.dates as dates
ax.xaxis.set_major_locator(dates.DayLocator(interval=3))
ax.xaxis.set_major_locator(dates.MonthLocator(interval=3))

#matplotlibのめっちゃまとめ
#https://qiita.com/nkay/items/d1eb91e33b9d6469ef51#64-%E8%BB%B8%E3%81%AE%E7%9B%AE%E7%9B%9B%E3%81%AE%E8%A8%AD%E5%AE%9A
```

#### ax_軸の調整_軸の日付の表示形式を変更

``` python
#デフォルトのyyyy-mmを、yyyymmddに変更
import matplotlib.dates as dates
ax.xaxis.set_major_formatter(dates.DateFormatter('%Y%m%d'))

#こちらも動くかチェック
#ax.xaxis.set_major_formatter(plt.DateFormatter('%Y%m%d'))

#matplotlibのめっちゃまとめ
#https://qiita.com/nkay/items/d1eb91e33b9d6469ef51#65-%E8%BB%B8%E3%81%AE%E7%9B%AE%E7%9B%9B%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A
```

#### ax_軸の調整_軸を関数で整形して表示

``` python
#この項目、不要と思ったら、そのうちのせないようにするかも
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x: 関数))
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x: 関数))
```

#### ax_軸の調整_軸を、底が10の対数で表示

``` python
from matplotlib.ticker import PercentFormatter
ax.yaxis.set_major_formatter(PercentFormatter(1))
```

#### ax_ラベルの回転

``` python
plt.setp(ax.get_xticklabels(), rotate = 45)
plt.setp(ax.get_yticklabels(), rotate = 45)
```

#### ax_pandasから作成するインスタンスをaxにする

``` py
ax_tmp = fig.add_subplot(111)

ax = df_base.plot(
    kind = ~:str, #'scatter' 'bar'など
    ~,
    ax = ax_tmp
)
#その後の例
ax.plot([0,1], [0,1])
```

#### ax_ギリシア文字を表示する

``` python
ax.title('$\\alpha$')
#latexは\が一つに対し、matplotlibは\\が二つ
```

#### ax_pyplotメソッドに共通_凡例用の名前を付ける

``` python
ax.~(~, label = "~")
#barだけ、なし
```

#### ax_pyplotメソッドに共通_作画の透明度を調整

``` python
#0.0~1.0
ax.~(~, alpha = 0.5)
```

#### ax_pyplotメソッドに共通_作画の色を調整

``` python
ax.~(~, color = )
#barだけ、(~, c = )
```

#### ax_pyplotメソッドに共通_作画の前後を調整

``` python
ax.~(~, zorder = )
```


#### その他_japanize_matplotlibライブラリ_日本語を表示する

``` python
#japanize_matplotlib
import japanize_matplotlib

#フォント指定
from matplotlib.font_manager import FontProperties
font_meiryo = FontProperties(fname = 'C:\\Windows\Fonts\meiryo.ttc')
plt.title('図タイトル', fontproperties = 'font_meiryo')

#linux: /usr/share/fonts/truetype/takao-pothic/~
#mac: /System/Library/Fonts/~
```

#### その他_seaborn_日本語を表示する

``` python
#seabornを利用する場合、"import japanize_matplotlib"が効かないのでフォントを指定する
#このフォントが入っているパソコンではこれでOK、ない場合他の日本語フォントを指定
import seaborn as sns
sns.set(font=["IPAexGothic"])
```

#### その他_seaborn_フォントサイズを指定

``` py
sns.set(font_scale=0.4)
```

#### その他_pdf形式で保存_PdfPages

``` python
from matplotlib.backends.backend_pdf import PdfPages

pdf_object = PdfPages('~.pdf')
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
for i in list_tmp:
    ax.plot(~)
    ax.~
    ax.~
    #画像をpdfに保存
    #pdf_object.savefig(fig)は、一つのpdf_objectの中で何回あってもいい
    pdf_object.savefig(fig)
    #これまでの描画をclearして次の描画ができるようにする
    fig.clear()
#pdfファイルを保存して閉じる
pdf_object.close()

#figsizeが全く異なる複数のfigでも1ファイルにまとめて出力される。
#figsizeに関係なく各figがページの全体になるよう描画される。
#figの縦横比と各ページの縦横比は同じくなるように出力される。パソコンで見ることを想定するのであれば横の長さが長くなるように設定したほうがいい。

#手作業でdf全体の可視化を表示する場合は、houseprise3を参照
```


#### その他_plot.show()を打たなくても作画を実行する

``` python
%matplotlib inline
```

### bar

#### 基本

``` py
ax.bar(x = x軸のリスト, height = 各棒の高さのリスト)
```

#### 引数一覧

#### dfから作成_複数プロット対応

``` py
#python
#pandasから作成
df_tmp.plot.bar()
#df_tmpに含まれるすべての値が、indexごとに棒グラフで表示される

#以下、オプション
plt.xticks(rotation = 90)
plt.grid(True)
plt.xlabel('label')
plt.show()
```

#### 3本重ねて書く方法

``` python
#棒グラフを横に重ねる方法はmatplotlibで実装されていないから、
#プロットする場所を横軸の座標で調整して横に重なるように見せる
import matplotlib.pyplot as plt
import numpy as np
import random

fig, axes = plt.subplots(1, 1, )

int_len = 5

list_height1 = list()
list_height2 = list()
list_height3 = list()

list_list = [list_height1, list_height2, list_height3,]

for i_list in list_list:
    for i in range(int_len):
        i_list.append(random.randrange(100))
 
list_xaxis = np.arange(int_len)
labels = ['a', 'b', 'c', 'd', 'e']
 
width = 0.2
 
axes.bar(list_xaxis+width*0, list_height1, width=width, align='center')
axes.bar(list_xaxis+width*1, list_height2, width=width, align='center')
axes.bar(list_xaxis+width*2, list_height3, width=width, align='center')

plt.xticks(list_xaxis + (width*2)/3, labels)
plt.show()

#参考:https://www.sejuku.net/blog/74185)
```

### histgram

#### 基本

``` py
ax.hist(数値のデータ:list or pd.Series)
```

#### 引数一覧

``` py
ax.hist(数値のデータ:list or pd.Series,
        range=(ヒストグラムの始め:int, ヒストグラムの終わり:int),
        bins=ヒストグラムの数:int,
        log = True/False: 縦軸を対数表示にするかどうか
)
```

#### dfから作成

``` py
#python
#pandasから作成
df_tmp['column_a'].plot.hist()
```

### box_plot

#### 基本

``` py
ax.boxplot(list:複数の箱ひげ図を作成するときはlistの各要素が、各箱ひげ図のlist)
```

#### 引数一覧

``` py
#軸は各値　頻度ではない
ax.boxplot(
    list
    , labels = list #各箱ひげ図の名前 # ax.legend()を打たなくても、表示される
    , vert = False #箱が横方向に伸びる形式で表示
)


```


### violin_plot

#### 基本

#### 引数一覧

``` py
#分布の形状も含めて、複数の数値型リストデータの分布を比較出来る
#箱ひげ図の持つ「複数の数値型リストデータの分布を横に並べて比較できる」利点をさらに拡張子した

```

### plot_line

#### 基本

``` py
ax.plot(横, 縦)
```

#### 引数一覧

#### 45度線

``` python
ax.plot([0, 最大値], [0, 最大値],)
```

#### 複数のプロットを重ねる

``` python
#スケール等を調整する場合if文でカラムごとに処理を加える
list_column = [column1, column2, column3]
for i_column in list_column:
    ax.plot(x, df_tmp.loc[:,i_column], label = i_column)

#同じプロットで時期によって色を変える方法
ax.plot(x, df_tmp.column1, label = 'phase1') #はじめに全区間でプロットすることで、色の変わり目でもプロットの線がつながるようになる
ax.plot(x, df_tmp.query('when1 < column_date & column_date < when2').column1, label = 'phase2')
ax.plot(x, df_tmp.query('when2 < column_date & column_date < when3').column1, label = 'phase3')

#各線の名前を付ける
plt.legend()
```

#### seabornの利用

``` py
sns.lineplot(
    x = 'x_name',
    y = 'y_name',
    data = (リスト型),
    ax = ax
)

#同じ内容
ax = sns.lineplot(
    x = 'x_name',
    y = 'y_name',
    data = (リスト型),
)
```

### plot_scatter

#### 基本



#### dfから作成

``` py
df_tmp.plot(kind = 'scatter') #df_tmp.plot.scatter() でもいいのでは
```

### plot_heatmap

#### 基本

#### 引数一覧

``` py
#分布範囲×分布の形状(色)を可視化する際に使用する
#scatter_plotの点が重なる場合に、点の分布の疎密を色で可視化する
#このプロットの解釈に色の情報が必要になる
```

### heatmap_相関行列

#### 基本

``` py
sns.heatmap(df_base.corr())
```

#### 引数一覧

``` py
#このプロットの解釈に色の情報が必要になる
#seabornを使う必要がある
import seaborn as sns

df_corr=df_base.corr()

fig=plt.figure()
ax=fig.add_subplot()

ax\
=sns.heatmap(
    df_corr
    , vmax=1
    , vmin=-1
    , center=0
    , square=True
    , ax=ax
    , cap=sns.color_palette("RdBu_r", 24)
)
```

## chapter_モデリング
<!-- md001と対応 -->

### 0x_通常の処理、モデリング全般の設計

``` py
object_model = model()
object_model.fit(x_train)
object_model.predict(x_test)

#「予測, 実績」の順に並べれば、そのまま引き算したときに上振れ、下振れとプラスマイナスのイメージが一致する。
```

#### tips

```
ハイパーパラメータのチューニングは、最後に行う
```

### 00_統計学

#### 確率分布_カイ二乗分布

``` py
#計算
import spicy
x2, p, dof, expect = spicy.stats.chi2_contingency(df_base)
```

### 01_一般化線形回帰

#### ライブラリのimport

``` python
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
```

#### 基本のモデリング

``` python
linear_regression = LinearRegression
linear_regression = fit(x_train, y_train)
```

### 02_決定木系

#### ライブラリのimport

``` python
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from catboost
```

#### 決定木_ノードの取得

``` python
import pydotplus
from sklearn.externals.six import StringIO
from sklearn.tree import export_graphviz

model = DecisionTreeRegressor()

output_object = StringIO()

export_graphviz(model,
                out_file = output_object, #または、'filename.dot'
                feature_names = list_features,
                special_characters = True)

graph = pydotplus.graph_from_dot_data(output_object.get_value())
```

#### RandomForest

#### xgboost

``` python
model = XGBRegressor(
            seed = 0,
            tree_method = 'hist',
            objective = 'reg:squarederror',
            learning_rate = 0.1,
            min_child_weight = 1000
)

model.fit(
    x_train,
    y_train,
    early_stopping_rounds = 50,
    eval_set = [(x_test, y_test)]
)

#何かのメソッド
model.best_score

#feature_importanceを取得
model_booster = model.get_booster()
model_booster.get_score(importance_type = 'gain')
```

#### lightgbm

#### catboost

### 03_サポートベクターマシン、カーネル法

#### ライブラリのimport

``` python
from sklearn.svm import SVR
```

#### ハイパーパラメータ

``` py
#SVC
#svrと共通する変数のデフォルトは、svrと共通
sklearn.svm.SVC(
    *, 
    C=1.0, 
    kernel='rbf', 
    degree=3, 
    gamma='scale', 
    coef0=0.0, 
    shrinking=True, 
    probability=False, #svrにはない
    tol=0.001, 
    cache_size=200, 
    class_weight=None, #svrにはない
    verbose=False, 
    max_iter=-1, 
    decision_function_shape='ovr', #svrにはない
    break_ties=False, #svrにはない
    random_state=None #svrにはない
)
```

``` py
#SVR
sklearn.svm.SVR(
    *, 
    kernel='rbf', 
    degree=3, 
    gamma='scale', 
    coef0=0.0, 
    tol=0.001, 
    C=1.0, 
    epsilon=0.1, 
    shrinking=True, 
    cache_size=200, 
    verbose=False, 
    max_iter=-1
)
```

### 04_ニューラルネット

#### ライブラリのimport

``` python
from sklearn. import 
```

### 05_ベイズ

#### ライブラリのimport

``` python
from sklearn. import 
```

#### RとStan時系列

``` r
#r
#.stanの書き方、ローカルレベルモデル
data {
    int n_sample;
    real y[n_sample];
}

parameters {
    real mu_zero;
    real mu[n_sample];
    real<lower=0> s_w;
    real<lower=0> s_v;
}

model {

    mu[1] ~ normal(mu_zero, sqrt(s_w));

    for(i in 2:n_sample) {
        mu[i] ~ normal(mu[i-1], sqrt(s_w));
    }

    for(i in 1:n_sample) {
        y[i] ~ normal(mu[i], sqrt(s_v));
    }

}
```



#### Pythonによるベイズ統計学入門

##### 反復探索法で連立方程式の解を求める_各種の最適化問題を解くための関数群optより

``` py
import scipy.optimize as opt
opt.root(連立方程式の関数, 初期値, args=関数に渡す変数)

#連立方程式の関数の書き方
def func_tmp(param_最適解の対象, a, b, c, ~):
    equation1 = param_最適解の対象, a, b, c, ~ の式
    equation2 = param_最適解の対象, a, b, c, ~ の式
    ↓
    return [equation1, equation2. ~] #または、np.hstack((equation1, equation2. ~))

#初期値は、func_tmpで一つ目の変数の初期値
#複数の変数を指定する場合は、ここをリスト型で入れる

#argsは、func_tmpの二つ目以降の変数の具体値を入れる (func_tmpの二つ目以降の変数は最適化の対象外)
```

##### 一様分布

``` python
import scipy.stats as st
st.uniform.pdf(x, loc, scale)
# x: 横軸上の座標
# loc: locationのこと、一様分布の開始地点
# scale: 一様分布の、開始地点から終わりまでの範囲
```

##### ベルヌーイ分布に従った乱数を発生

``` py
st.bernoulli.rvs(p, size=10000)
# Random VariableS (または、Random VariableS)
# ’a random variate is a particular outcome of a random variable’
#WIKIより、https://en.wikipedia.org/wiki/Random_variate
```

##### ベータ分布

``` python
st.beta.pdf(x, alpha, beta, loc, scale)
# ベータ分布：1-0の事象が、1がα回_0がβ回派生する事象の(このあとtba)
#Probability Density Function

st.beta.cdf()
#Cumulative Density Function

# keisukeのブログ scipy.stats - scipyの統計関数群のAPI http://kaisk.hatenadiary.com/entry/2015/02/17/192955
```

##### ベータ分布_基本統計量

``` py
import scipy.stats as st
st.beta.mean(a, b)
st.beta.median(a, b)
st.beta.std(a, b)
st.beta.interval(prob, a, b)

```

##### ガンマ分布_something

``` py
aaa
```




### 06_因果推論

#### ライブラリのimport

``` python
from sklearn. import 
```

### 07_時系列データの解析

#### ライブラリのimport

``` python
from sklearn. import 
```

### 08_強化学習

#### ライブラリのimport

``` python
from sklearn. import 
```

### 09_クラスタリング

#### ライブラリのimport

``` python
from sklearn. import 
```

### 10_自然言語処理
(memo20210131 10_tba→10_自然言語処理)

```
pre-trained model: BERTなど、すでに学習が完了しているモデル
```

# title_メソッド対応表_コーディング一般

## ファイル、ディレクトリ、リンク、パスの操作

### ファイル

#### ファイル_読み込み_with_open()

``` python
with open('filename.txt', mode='~') as f:
    str_txt = f.read()
#with open()を使えばインデントの処理が終わったタイミングでファイルを自動で閉じる
#open()を使う場合、必ず.close()で閉じる必要がある
#慣例で、f、がよく使われる

#modeの引数
#'r':読み込み
#'w':新規作成/書き込み
#'x':新規作成のみ
#'a':追記
```

#### ファイル_読み込み_pd_read_csv()

``` python
#dfの読み込み
pd.DataFrame(data,columns=[column1,column2])

pd.read_csv(
    'filename'
    , encoding="文字コード" #"cp932", "utf-8", "shift-jis"など
    , dtype = {'column1': object, 'column2': object} #型指定
)
```

#### ファイル_読み込み_np_load()

``` python
#npz の読み込み
np.load(filename)
```

#### ファイル_読み込み_Windowsサーバから

``` python
#python
import pathlib
filepath = 'パス_ファイル名.csv'
read_file = pathlib.WindowPath(filepath)
```

#### ファイル_読み込み_オンラインから

``` py
import urllib
param_url = 'https://~/~/~.file'
urllib.request.urlretrieve(param_url, 'path/filename.file')
```

``` sh
curl ダウンロード先のパス URL
```

#### ファイル_書き出し_to_csv()

``` python
pd.DataFrame().to_csv('filename'
                        , index=False
                        , encoding="cp932"
                     )
```

#### ファイル_書き出し_np_savez()

``` python
#python_numpy

#npz の保存
np.savez(pathname, filename1 = np.array('1'), filename2 = np.array('2'))
```

#### ファイル_書き出し_savefig()

``` python
#python_matplotlib
#画像の保存
plt.savefig('filename.png', dpi = 300)
#dpi: 画像の解析度
```

#### ファイル_書き出し_pickle_dump()

``` python
#python_sklearn
#モデルの保存
import sklearn
import pickle
reg = sklearn.LinearRegression().fit(x,y)
with open('filename.pickle', mode = 'wb', as f
    pickle.dump(reg, f)
```

#### ファイル_書き出し_実行結果出力_text

``` sh
#標準出力を保存
#出力ファイルは、事前に作っておく必要はない
#既にファイルがあっても上書きされるので、注意が必要
ls > text.txt

#既存ファイルの最後に追記する場合
ls >> text.txt

#転記 #### リダイレクトの記法
< FILE        標準入力をFILEに変換する(ここで、標準入力に関することはこれだけ) (入力ダイレクト)
> FILE        標準出力をFILEに変換する
>> FILE       標準出力の出力をFILEの末尾に追記する
2> FILE       標準エラー出力をFILEに変換する
2>> FILE      標準エラー出力の出力をFILEの末尾に追記する
> FILE 2>&1   標準出力と標準エラー出力を、ともにFILEに変更する
```

#### ファイル_コピー

``` python
#py
import shutil

#出力先にファイルを指定
shutil.copy('file_name.py', 'file_name_copy.py')

#出力先にディレクトリを指定
shutil.copy('file_name.py', 'directry_name')
```

``` sh
#sh
cp file_name.py file_name_copy.py
cp file_name.py directry_name #空白スペースで複数ファイルを指定することができる
# コピー先のファイル名のファイルが存在していても、無条件で上書きされる、上書き防止のため確認をさせるには、-iオプションを追記
# 特定の拡張子のファイルをすべてコピーするのは、cp *.py directry_name
```

#### ファイル_移動

``` sh
#sh
mv file_name.py directry_name #空白スペースで複数ファイルを指定することができる
```

#### ファイル_新規作成

``` py
with open('filename.txt', mode='x') as f: 
#xは新規作成のみ、wにすると、新規作成or書き込み
```

``` sh
touch file_name.txt
#複数のファイルを作成する場合は、コマンドの後にスペースでつなげる、touch a.txt b.txt
#拡張子は何でも大丈夫
#既存のファイルがある場合は、新規作成はされない
```

#### ファイル_内容の表示

``` sh
cat filename
#引数が複数ある場合、コマンドの後に空白スペースで渡すことができる。
#catは、concatnateのcat、引数を複数指定した場合、結合したように表示するから
```

``` sh
less filename
#コマンドの画面に移る範囲内で、内容を表示
#次に行くにはfまたはスペース、前に戻るのはb
#検索は/

#d:画面半分下にスクロール
#u:画面半分上にスクロール
#g:1行目に移動
#G:最後の行に移動
#X:lessを終了したときに表示していた内容をクリアにしない
```

``` sh
head filename

# 上位n行表示
#head -n filename
```

#### ファイル_削除

``` py
rm file.txt

#複数のファイルを削除する場合は、空白スペースでコマンドの後に記載
#ディレクトリを削除する場合は、rm -r file.txt

#rmdir dir1 空ディレクトリだけ削除するコマンド、隠しファイル、.a.txt、があっても実行されない
```

#### ファイル_検索

``` sh
find ディレクトリ検索開始 -name 検索するファイル名 -print

#カレントディレクトリで検索を開始知る場合は、ディレクトリの入力を省略できる
#ワイルドカードを使う場合は、かっこで囲む
#-inameとすることで、ファイル名の大文字小文字を区別しない
find -iname '*.txt' -print

locate 検索するファイル名(ここに含まれるワードがパス二含まれていても表示される)
#一日一回ファイルのデータベースを作成し、コマンド実行時にそこから探すから、ディレクトリーツリーを下るfindコマンドよりも検索が早い
#ファイル名だけから検索する場合、locate -b 検索するファイル名
```

#### ファイル_サイズを表示

``` sh
#バイト数を表示
wc -c filename.txt

#行数を表示
wc -l filename.txt

#単語数を表示
wc -w filename.txt
```

#### ファイル_ファイル内の特定の1文字を変換

``` sh
tr a A < file.txt
#別の方法、cat file.txt | tr a A
#標準入力に対してのみ作用する、ファイル名引数に指定できない
#複数の要素を変換、abc ABC
#アルファベット順で指定、a-z A-Z

#特定の文字の削除
tr -d 削除する文字

#改行の削除
tr -d "\n"
```

#### ファイル_ファイル内の特定の文字列を変換(grep)

``` sh
#ここでsedやawkが使われることも

#抽出
grep param file.txt
ls | grep param

#行数を表示する場合
grep -n param

#大文字小文字を区別しない場合
grep -i Param

#特定の文字列を含まない行を抽出する場合
grep -v param

#行頭がparam
grep '^param'

#行末がparam
grep 'param$'

#任意の一文字
#直前に、\、を置いてメタ文字の意味を打ち消す(エスケープする) grep '\.txt'
grep 'p.ram'
grep 'p..am' #2字の場合

#特定の文字を指定する
grep 'pa[rl]am' #paramとpalamが返る

#指定した文字以外とのマッチ
grep 'param[^something]' #paramが含まれる、かつparamsomethingが含まれない文字列が返る

#特定の1文字の繰り返しを指定するメタ文字
grep 'be*r' #eが、0回以上繰り返される(0回:br)

#複数の1文字の繰り返しを指定するメタ文字
grep 'b[ea]*r' #eまたはaが0回以上

#任意の1文字の繰り返しを指定するメタ文字
grep 'b.*r' #'^txt_2021.*.txt'などで使われる

#特定の1文字の繰り返しを指定するメタ文字
#拡張正規表現
grep 'be*r'
grep -E 'be+r' #1回以上の繰り返し、0回の場合は含まない
grep 'be\+r'

#特定の1文字の繰り返し、0回または1回、を指定するメタ文字
#拡張正規表現
grep 'be?r'

#繰り返しの回数を指定するメタ文字
#拡張正規表現
grep -E 'be{n, m}r' #m回以上、n回以下、例'be{1, 2}r'
grep -E 'be{n}r' #ちょうどn回の繰り返し、例'be{1}r'
grep -E 'be{n,}r' #n回以上の繰り返し、例'be{1,}r'

#特定のグループの繰り返しを指定するメタ文字
#拡張正規表現
grep -E '(wine){2,}' #wineのグループを2回以上繰り返す

#特定のグループの繰り返し、複数を指定するメタ文字
#拡張正規表現
grep -E 'your (wine|beer)' #your wineかyour beerが含まれる文字列を返す

#### ファイル間の差分を確認する

``` sh
diff file1.txt file2.txt
```

#### ファイル_configファイル_yaml

``` py
#読み込み
import yaml
with open('file_name.yaml') as f:
    config_load = yaml.safe_load(f.read())
```

``` yaml
# yamlファイルの書き方

key1: 'value1'
#コロンの後は、必ずスペースを入れる

key2: ['value2_1', 'value2_2']

key3: 
    key3_1: 'value3_1'
    key3_2: 'value3_2'
    key3_3: 'value3_3'
#valueに、辞書型を1セット入れることも出来る

key4: 
    - 'value4_1'
    - 'value4_2'
    - 'value4_3'
#valueの部分がリスト型でかえる
```

#### ファイル_アーカイブ_tar

``` sh
アーカイブとは、複数のファイルやディレクトリをまとめたファイルのこと
複数ファイルをメールで送付する場面などで利用される

#アーカイブ
tar -cf アーカイブファイル アーカイブ元ファイルパス/ディレクトリ
例、tar cf dir1.tar dir1
パーミッションやオーナー、タイムスタンプなどの属性もそのままアーカイブ
rootにしか権限がついていないファイルは、一般ユーザではアーカイブや展開が出来ない

#展開
tar -xf アーカイブファイル

#アーカイブに加えて圧縮も行う場合
tar -czf dir1.tar.gz dir1
#tarの引数に、z、も追加する
#別の方法、tar -cf - dir1 | gzip -c > dir1.tar.gz

#展開_圧縮とアーカイブの展開をまとめて行う
tar -xzf dir1.tar.gz
#別の方法、gzip -d -c dir1.tar.gz | tar xf -56rr6t

#内容の表示
tar -tf アーカイブファイル
```

#### ファイル_圧縮_zip

``` py
zipファイル:データのアーカイブと圧縮を同時にやる

#アーカイブと圧縮

#展開
import zipfile
with zipfile.ZipFile('path_of_zip/filename.zip') as f:
    f.extractall('path_to_save')
```

``` sh
#アーカイブと圧縮
zip -r 圧縮ファイル名 圧縮対象パス

#展開
unzip 圧縮ファイル名.zip

#アーカイブと圧縮_パスワード付き
zip -er 圧縮ファイル名 圧縮対象パス
#引数eを付ける
#パスワード入力画面が表示される
#パスワード付きzipの展開コマンドは通常のコマンドと同じ

#内容を確認
zipinfo 圧縮ファイル名.zip
```

#### ファイル_圧縮_gzip

``` sh
#圧縮
gzip 圧縮元ファイル
#圧縮元ファイル.gz、というファイルが作成される
#元のファイルは削除される

#展開
gzip -d 圧縮元ファイル.gz
#圧縮元ファイルが残り、圧縮元ファイル.gz、は削除される
#gunzipコマンドの処理は、gzip -d と一緒


```

#### ファイル_圧縮_bzip2

``` sh
#gzipよりも圧縮率が高い:圧縮後のファイルサイズは小さいが、処理に時間がかかる

#圧縮
bzip2 圧縮元ファイル

#展開
bzip2 -d 圧縮元ファイル.bz2
```


### ディレクトリ

#### ディレクトリの内容を表示_そのディレクトリの内容のみ

``` python
import glob
glob.glob('path/*')
```

``` sh
ls パス
# ls dir/*.txt 任意の文字
# ls dir/?.txt 記号分の文字、今回は1文字

ls /usr /home #複数の引数(パス)を持てる
ls *.bash #正規表現に該当するファイルのみを表示
ls -l #ファイル属性を合わせて表示
ls -a #隠しファイルも表示
ls -F #ファイルであれば、名前の後に/がつく
ls -alF #上記のオプションを一度に指定 ls -a -l -Fと分けてもいい
ls -d #ディレクトリのみ表示

#ls -lの見方
#ファイルタイプ(-:通常オプション,d:ディレクトリ,l:シンボリックリンク)ファイルモード(パーミッションを表す) 1 ファイルの所有者(オーナー) ファイルが所属するグループ 43416 年月
#例、-rwxr-xr-x 1 root root 43416 Sep  5  2019
#ファイルモード(パーミッションを表す)の見方
#3文字ごとに分けられる、前から、オーナー/グループ/その他ユーザ
#r:read読み取り,w:write書き込み,x:execute実行,禁止のところは-(ハイフン)
```

#### ディレクトリの内容を表示_そのディレクトリ以下のすべての内容

``` python
os.walk(param_path)
```

#### ディレクトリのコピー

``` python
#py
shutil.copytree('directry_name', 'directry_name_copy')
```

``` sh
#sh
cp -r directry_name directry_name_copy
```

#### ディレクトリの移動

``` sh
#sh
mv directry1 directry2
```

#### ディレクトリの作成

``` py
import os
os.mkdir()
os.makedirs(directry_name)

#深い層のディレクトリを作るのに対応しているのは、os.makedirs()のみ

#すでにディレクトリが存在する場合にスキップする
os.makedirs(directry_name, exist_ok=True)

#上記、書き換え
# すでに作成されている場合にエラーが返らないようにする、すでに作成されているフォルダに加工はしない
if os.path.exists(directry_name) == False
    os.makedirs(directry_name)
```

``` sh
mkdir directry_name

#深い層のディレクトリを作る場合
mkdir -p dir_a/dir_b/dir_c/directry_name

#パスがないことを確認
! -e (パス)
```


#### ディレクトリが空の場合のみ、ディレクトリを削除する
 
``` sh
rmdir dir_empty
```

#### ディレクトリの検索

``` sh
#-type dで、ディレクトリを検索(シンボリックリンクの場合は、l)
#-a、は、andのa、省略可能
find -type d -a -name param_dir -print
```

#### ディレクトリ以下のファイルサイズの表示

``` sh
#-bで、バイト数の表示を指定している
du -b /dir_name/*

#メガ、ギガ単位で表す
du -h /dir_name/*
```

#### ディレクトリ以下のファイル数を表示

``` sh
ls /dir_name | wc -l
```

### リンク

#### リンクの作成

``` sh
#sh
ln -s link_base_file created_link_name
#-sオプションを入れないと、シンボリックリンクでなく、ハードリンクが作成されるが、ハードリンクの操作は難しいため、シンボリックリンクを作成する
#削除する場合は、rmコマンドを使用する
```

### パス


#### 環境パスを表示

``` sh
echo $PATH

printenv
```

#### 環境パスを追加

``` py
import sys
if new_path not in sys.path:
    sys.path.append(src)

#続けて、pyファイルから関数の読み込み
#ディレクトリ"src"以下のファイルから関数を読み込む
from filename.py import func_name
```

``` sh
PATH="$PATH:~/param_dir"
```

``` sh
#環境パスを追加した時の一連の流れ
root@PC:~# homesize.sh
homesize.sh: command not found
root@PC:~# cat /root/bin/homesize.sh
#!/bin/bash
du -h ~ | tail -n 1
root@PC:~# PATH="$PATH:~/bin"
root@PC:~# homesize.sh
64K     /root
```

#### パス_絶対パスの取得

``` python
import pathlib
pathlib.Path('path_name').resolve()

import os
os.path.abspath('path_name')
```

#### パス_パスの作成

``` python:pythom
os.path.join('.', 'dir1', 'src')
```

## 関数、クラス、イテレーション(for/while/case)、条件処理(if)の処理

### 関数

#### 基本

``` python
#def、を使用
def_func_name(parameter1, parameter2):
    処理
    return 戻り値

#引数に複数の要素を入れる場合
#慣例として、*args,**kwargsが使われている　それ以外の変数名でもいい
#1.*args
def func1(*args):
#変数をカンマ区切り：args=(1,2,3,4)で渡すことが出来る
#2.**kwargs
def func2(**kwargs):
#変数を辞書型で渡すことが出来る

#lambda、を使用
lambda parameter: 戻り値の式(parameter)

#lambda、を使用_一行で表現
(lambda parameter: 戻り値の式(parameter))(parameter_instance)
```

``` sh
function 関数名 ()
{
    処理
}

function、または最後の()を書かなくても、関数の定義ができる
()の中には何も書かない、変数を指定したりもしない
```

#### 関数のdocstring(document string)

``` python

#アノテーション
#主に、共有しないコードのなかで使用
#Pythonではじまる、型のある世界
#https://qiita.com/icoxfog417/items/c17eb042f4735b7924a3
def func1(parameter_path:str, parameter_date:int, parameter_df:pd.DataFrame) -> pd.DataFrame:
    処理
    return df_output

#docstring
#主に、共有するコードのなかで使用
#ダブルクオテーションで囲む
#[Python]可読性を上げるための、docstringの書き方を学ぶ（NumPyスタイル） https://qiita.com/simonritchie/items/49e0813508cad4876b5a
#numpydoc docstring guide https://numpydoc.readthedocs.io/en/latest/format.html
def func1()
    """
    Short summary：関数の説明をひとことで書く

    Parameters
    ----------
    parameter_path : str
        パス
    parameter_date : int
        日付
    parameter_df : pd.DataFrame
        データフレーム

    Returns
    ----------
    df_output : pd.DataFrame
        処理をした後のデータフレーム

    Notes
    ----------
    関数についてのコメントを書く
    """

    処理

    return df_output

```

#### 条件によって行う処理を変える場合の記法

``` python:python
def func1(param_set, flag_true == true):
    def func2(param_set):
        処理
    if flag_true:
        func2(a)
    else:
        func2(b)
#param_setは、同じ変数のセット
```

#### 条件によってreturnを変える場合の記法

``` python
def func1():
    if a==b:
        処理1
        return 1
    else:
        処理2
        return 2
```


### クラス

#### クラスメソッド

``` py
# クラスメソッド、インスタンスではないクラスをインスタンス化するためのメソッド
# 参考 メソッド、インスタンス化したクラスに使う

# 簡単にクラスをインスタンス化できるのがメリット
# 例、some_class.get('xxxx.id')

class A:
    @classmethod
    def my_class_method(cls):
        return 'Hello'
A.my_class_method()  #'Hello'が返る
```

### イテレーション(for/while/case)

#### 基本

``` py
#for 
for i in list_tmp:
    処理

#while
while 条件:
    処理
```

``` sql
#case
case when ~ then ~; else if ~ then ~;
```

``` sh
#for
for i in リスト
do
    処理
done

+リスト
スペース区切りで書くことも
または、*.txtなどと指定して、パス名を展開することもできる
seqコマンドで、$(seq 1 5) を指定することで、1~5の整数のリストを指定できる

#while
while 条件
do
    コマンド
done

条件が0:Trueの場合は繰り返し処理が実行される
算術式展開: $((計算式))と二重のかっこでくくることにより、中に書いた文字列を計算式として扱うことができる
iの値を増やすための処理(算術式展開): $((i + 1))

#case
case 文字列 in
    条件1)
        処理1
        ;;
    条件2)
        処理2
        ;;
esac

esac: caseを逆から読んだ
上から順に実行
何もマッチしなかったらcase文を抜ける
上記以外(if文でいうelse)
複数パターンをチェックする場合、a | b | c ,,,
```

#### 複数要素のイテレーション

``` python
#zip
for i_column1, i_column2 in zip(df_tmp.column1, df_tmp.column2):

#itertools
for i,j in 
    permutations(i,j): 順列
    combinations(i,j): 組み合わせ
    products(i,j):     直積

#豆知識、zipを使ってdfをdictにする
dict(zip(df_tmp.column_a, df_tmp.column_b))
```

#### イテレーションの番号を入れる

``` python
for i in enumerate(df_tmp.column):
```

#### DataFrameのイテレーション

``` python:python
#1.to_dict()を使う
list_df_tmp_dict = []
for i in range(len(df_tmp)):
    list_df_tmp_dict.append( df_tmp[i].to_dict() )
for i in range(len(list_df_tmp_dict)):
    list_df_tmp_dict[i]['column1']

#2.iterrows()を使う
for i_enumerate, row in df_tmp.iterrows():
    row.column1
```

#### イテレーション処理の途中で止める

``` python
#イテレーションの処理を中断し、次のイテレーションの処理を始める。
#イテレーションがネストになっている場合は、その処理のイテレーションを中断する。その処理の上のイテレーションまでは戻らない。
continue
pass
break
```

### 条件処理(if)

#### 基本

``` py
#python
if (条件):
    ~
    ~
elif (条件):
    ~
    ~
else:
    ~
    ~

#複数条件の場合
#(条件)and(条件)、または、(条件)or(条件)
```

``` sh
#sh
#通常のプログラミング言語と違いif,elifの後に置くのは、コマンド、である
#"["は組み込みコマンドであり、"["の後にはスペースが必要、 ("]"は引数)
if コマンド1; then
    処理1
elif コマンド2; then
    処理2
else
    処理3
fi

#複数条件の場合
and: 条件式1 -a 条件式2 ($$) 、例、if [ -d "~" -a -r "~" ]; then
or: 条件式1 -o 条件式2 (||8)
not: !条件式

#[コマンドは、そのあとに続く処理が正常に終了した場合は0を、それ以外の場合は0以外を返す。
#[コマンドと類似したコマンドに、testコマンドがある
#[コマンド以外にも使用できる例として、通常のコマンドに-q:quiet引数を指定し終了ステータスだけを表示する
#例、if grep -q 'bash' /etc/passwd/; then これは、0か0以外を返す

#[コマンドの引数_文字列の場合
str1 = str2: str1とstr2が等しい
str1 != str2: str1とstr2が等しくない
-z str1: str1が空文字列である
-n str1: str1が空文字列でない

#[コマンドの引数_intの場合
以下の、いづれかを使うことがある <!-- 詳しくは『新しいLinuxの教科書』293p -->
-eq,-ne,-lt,-le,-gt

#[コマンドの引数_ファイル属性の場合
-e file: fileが存在する
-d file: fileがディレクトリである
-f file: fileが通常のファイルである
他
```

#### True/Falseの場合は、' = True'を省略できる

``` python
#例
if ~.isnull():
    処理
```

## 実行の管理

<!--
処理時間の計算
正規表現
ライブラリ・パッケージ
-->

### 処理時間の計算

``` python
#timeライブラリ
import time
#処理の初め
time_start = time.time()
#処理の終わり
time_end   = time.time()
print(time_end-time_start)

#コンテキストマネージャ

```

### 正規表現

``` python:python
# r
#str_文字列に含まれる正規表現を無効化する
r'str_文字列'
#パスに正規表現が含まれる場合の対処
r'path_name'

#f
#文字列に変数を埋め込む
param_a = 'a'
param_b = 'b'
f'{param_a} before {param_b}'
```


#### 権限

``` sh
#特定のファイルの権限の変更
chmod (誰から)(どうする)(どの権限を) ファイル名

#rootユーザ権限を継続
su

#rootユーザ権限で一回実行
sudo
```



### ライブラリ・パッケージ

#### インストール

シェルから実行

#### ライブラリの逐次読み込み

``` python:python
#jupyter上で実行
%reload_ext autoreload
%autoreload 2
#%autoreloadの後を''や'1'にすることで、読み込む回数を減らすことが出来る
```

#### ソースファイル間でライブラリの読み込み

``` python:python
#同じディレクトリ
from .src_file import function

#隣のディレクトリ
from .dir.src_file import function
```