python備忘録(逐次更新)

# 項目
1. 文字列とかをコード(代入文)として使いたいとき`eval`
2. histで２つを重ね合わせて一方を透明にしたい時`.hist(alpha = 0.5)`
3. 平方根を使いたい!```math.sqrt(x)```
4. numpyがそのまま使えるリストを作りたい!```np.array([0, 1, 2])```
5. 数値データの分散を即効見たい `.var()`
6. グラフを一回の処理で纏めて並べて表示したい`plt.subplot()`
7. `[[A,B,C],[D,E,F]]`みたいな多次元リストを一次元化`itertools.chain.from_iterable()`
8. リストに挿入`.insert()`
9. リストの要素を削除するやつ`pop,del,remove,clear`
10. 辞書型で要素削除`pop,popitem,del`
11. `if not文`メモ
12. 変数の型を`if`で確認する`isinstance(変数, 型)`
13. 小数点以下を切り捨て`math.floor()`
14. リストの要素頻度カウント
15. 辞書のソート
16. 辞書をcsvに
17. ディレクトリ中のPATH取得
18. 少数部を丸める
18. df同士の内部結合
18. dfのカラムを取得
18. dfの列を削除
18. df内の欠損値があるレコードを削除する
18. dfのカラムを並び替える
18. 例外処理(エラーが出た際の)
18. リストや文字列を逆順にする
18. リストが空かを判定
18. リストを結合
18. リスト内の要素の場所を取得
18. コマンドライン引数を受け取る
18. リスト、文字列を交互に変換
18. numpy配列、リストを交互に変換
18. 文字列中の特定の文字を置換
18. dfを1行ずつ取得する
18. 画像のexifからメタデータを取得
18. 再起関数
18. グラフのリアルタイム描画
18. グラフのリアルタイム描画2
18. 標準入力の高速化

# 1. 文字列とかをコード(代入文)として使いたいとき`eval`
`eval("~~~")`で中の文字列をコードとして使える、所謂代入文てやつ？

```python:python
list = ["dog","cat"]
dog, cat = "wan", "nya"
for i in list:
  print(eval(i))

# wan
# nya
```

# 2. histで２つを重ね合わせて一方を透明にしたい時`.hist(alpha = 0.5)`
`.hist(alpha = ?)`で透明化、`1~0`で`1`に近いほど濃くなり、`0.0`で完全透明化。

```python:python
x = np.random.randn(10000)
plt.hist(x, alpha =0.5)
plt.hist(x - 2, alpha = 0.5)
plt.show
```
![スクリーンショット 2020-11-10 0.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649647/d809a149-afa6-88a7-48a7-02215314b13f.png)

# 3. 平方根を使いたい!`math.sqrt(x)`
平方根を簡単に使いたい! そんなときは`math`で`.sqrt(x)`!

```python:python
import math
print(math.sqrt(4))
print(math.sqrt(144))

# 2.0
# 12.0
```

# 4. numpyがそのまま使えるリストを作りたい!`np.array([0, 1, 2])`
`np.array([intのリスト])`でリストを作ることで、そのままリストにnumpyモジュールを適用できる。

```python:python
x = np.array([812, 973, 1001])
np.max(x)

# 1001
```

# 5. 数値データの分散を即効見たい `.var()`
```python:python
import numpy as np

x = [1,2,3,4,5]
np.var(x)

#2.0
```

- `np.var(データ)`でとりあえず分散が出る
- `axis(2列目に記載)`で数値を指定することで、行列データの行を選択して分散を出せる
- `ddof=0`と記載で標準偏差、`ddof=1`で不偏分散

# 6. グラフを一回の処理で纏めて並べて表示したい`plt.subplot()`
```python:python
plt.subplot(1,2,1)
plt.hist(np.random.choice(10, 100))
plt.subplot(1,2,2)
plt.hist(np.random.choice(10, 100))
```

![スクリーンショット 2020-12-01 2.01.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649647/cba320cb-28b1-b7c0-175e-b42d9209142e.png)

- `plt.subplot(行数、列数、順番基準でどこに置くか)`

# 7. `[[A,B,C],[D,E,F]]`みたいな多次元リストを一次元化`itertools.chain.from_iterable()`
```python:python3
#これを一次元化したリストに
x = [[A,B,C],[D,E,F]]

print(list(itertools.chain.from_iterable(x)))

#[A,B,C,D,E,F]
```

# 8. リストの場所を選択して挿入`.insert()`
```python:python
x = [B,C]
x.insert(0,A)

print(x)
#[A,B,C]
```

# 9. リストの要素を削除するやつ`pop,del,remove,clear`
```python:python
#位置を指定して削除
#`pop`の場合は削除した値が返ってくる
x = ["A","B","C"]
x.pop(0)

#"A"
#["B","C"]

#スライスして削除
#`del`は削除した値は返らない
del x[1]

#["A","C"]

#要素から削除
x.remove("C")

#["A","B"]

#全削除
x.clear()

#[]
```

# 10. 辞書型で要素削除`pop,popitem,del`
```python:python
#pop,普通のリストと同じ
#keyを指定して削除
x={"A":1,"B":2,"C",3}
rv = x.pop("A")

print(x)
print(rv)

#{"B":2,"C",3}
#1

#popitem
#一番最後のkeyとvalueを返し、削除する
key_1,value_1 = x.popitem()
print(key_1)
print(value_1)

#"C"
#3

#del
#keyで指定する、値は返らない
del x["A"]
print(x)

#{"B":2,"C",3}

#複数
del x["B"],x["C"]
print(x)

#{}
```

# 11. `if not文`メモ
```python:python
str1 = "apple"
if not str1 == "orange":
    print(True)
else:
    print(False)
```

# 12. 変数の型を`if`で確認する`isinstance(変数, 型)`
```python:python
x = "Hell World"

if isinstance(x, int):
  print("intです")
else:
  print("strです")
```

# 13. 小数点以下を切り捨て`math.floor()`
```python:python
print(math.floor(5.4321))
# 5

#負の場合
print(math.floor(-5.4321))
# -6

#こうなっちゃうので
print(int(-5.4321))
# -5
#こんな感じも出来る
```

# 14. リストの要素頻度カウント
```python:
import collections

x = ["あ","い","う","え","あ"]
y = collections.Counter(x)
print(y)
#Counter({'あ': 2, 'い': 1, 'う': 1, 'え': 1})
```

# 15. 辞書のソート
```python:
#aは辞書
#降順、昇順はリバース消す

tuple_sorted = sorted(a.items(), key=lambda x:x[1], reverse=True)
#タプルなんで辞書にしとく
dict_sorted = dict(tuple_sorted)
```

# 16. 辞書をcsvに
```python:
import csv

with open('csv名.csv', 'w') as f:  
    writer = csv.writer(f)
    for k, v in 辞書名.items():
       writer.writerow([k, v])
```

# 17. ディレクトリ中のPATHを取得
```python:
import os

path = "ディレクトリのPATH"

files = os.listdir(path)
print(files)
```

# 18. 少数部を丸める
```python:
x = 12.3456

print(round(x))
#12
print(round(x,1))
#12.3
```

# 19. df同士の内部結合
```python:
pd.merge(df_1, df_2, on='結合キー', how='inner')
```

# 20. dfのカラムを取得
```python:
df.columns.values()
```

# 21. dfの列を削除
```python:
df.drop(columns=['カラム1', 'カラム2'])
```

# 22. df内の欠損値があるレコードを削除する
```python:
df.dropna(how='any')
```

# 23. dfのカラムを並び替える
```python:
#新たなdfが生成される
x = df.reindex(columns=['a', 'b', 'c'])
```

# 24. 例外処理
```python:
a = 0
b = 3
try:
  print(a/b)
except: #全てのエラーを検知
  print('Error')

# Error
#エラーを限定したい場合は"except TypeError as e:"の様にエラーを指定
```

# 25. リストや文字列を逆順に
リストを逆順に

```python:
#関数使用
li = [1, 2, 3, 4, 5]
reverse_li = reversed(li)

#スライスで
reverse_li = li[::-1]
```
文字列の場合

```python:
#スライスで
str = "abcde"

reverse_str = str[::-1]
```

# 26. リストが空かを判定
```python:
li = []
if not li:
 print("None")

if len(li) == 0:
 print("None")
```

# 27. リストを結合
```python:
li_1 = [1,2,3]
li_2 = [7,8,9]

li_1.extend(li_2)
print(li_1)

#[1,2,3,7,8,9]
# li += ~~~ でもok
```

# 28. リスト内の要素の場所を取得
```python:
li = ["a","b","c","b"]
print(li.index("a"))
# 0

#要素全ての場所が欲しい場合(内包表記)
print([i for i, x in enumerate(li) if x == "b"])
#[1,3]
```

# 29. コマンドライン引数を受け取る
```python:
import sys
argv = sys.argv

print(argv[0],argv[1],argv[2])

#$ python3 app.py a b

#app.py a b
```

# 30. リスト、文字列を交互に変換
```python:
#リストを文字列に
li = ["a","b","c"]
print(','.join(li))
#a,b,c

#数値を含む場合
li = ["a",1,"b"]
print(','.join(map(str, li)))
#a,1,b 
#map()を用いる事で、第一引数にある関数を第二引数のものに適用している

#文字列をリストに
str = "a,b,c"
print(str.aplit(","))
#[a,b,c]
```

# 31. numpy配列、リストを交互に変換
```python:
#リストをnumpy配列に
li = [1,2,3]
np_li = np.array(li)
#np.array(li, dtype=データ型)でデータ型を指定出来る
#[1 2 3]

#numpy配列をリストに
li_2 = np_li.tolist()
#[1,2,3]
```

# 32. 文字列中の特定の文字を置換
```python:
str = "abc\ndef"
print(str.replace('\n',''))

#abcdef
```

# 33. dfを1行ずつ取得する
```python:
#df.itertuples()
for i in df.itertuples():
  print(i)
#タプル形式で取得される
```

# 34. 画像のexifからメタデータを取得
```python:
from PIL import Image
import PIL.ExifTags as ExifTags

def get_gps(file_path):
    im = Image.open(file_path)
    # exifを辞書型で取得
    exif = {
        ExifTags.TAGS[k]: v
        for k, v in im._getexif().items()
        if k in ExifTags.TAGS
    }
    # gpsを指定
    gps_tags = exif["GPSInfo"]
    gps = {
        ExifTags.GPSTAGS.get(t, t): gps_tags[t]
        for t in gps_tags
    }
    # 緯度軽度に変換
    def conv_deg(v):
        # 分数を度に変換
        d = float(v[0])
        m = float(v[1])
        s = float(v[2])
        return d + (m / 60.0) + (s / 3600.0)
    lat = conv_deg(gps["GPSLatitude"])
    lat_ref = gps["GPSLatitudeRef"]
    if lat_ref != "N": lat = 0 - lat
    lon = conv_deg(gps["GPSLongitude"])
    lon_ref = gps["GPSLongitudeRef"]
    if lon_ref != "E": lon = 0 - lon
    return lat, lon
```

# 35. 再起関数
再起関数をいい加減使いこなしたい
### 簡単な定義
関数が自らの中で自らを呼び出す処理。<br>
何か大量のデータの各値ごとに反復した処理を行いたい場合、再起関数を用いて処理データを徐々に削っていく事で、毎回大きなデータを回すよりも処理が速くなる。(合ってる?)
### 基本的な形式

```python:
def saiki(n):
    # 終了条件
    if n == 0:
        return 0
    # 終了条件に当てはまらない場合、関数内の引数を用いて反復したい処理をreturnする
    else:
        return n + saiki(n-1)
```
基本的に再起関数は、上記の様に反復を停止させる終了条件、及びに反復させたい処理で構成される。<br>
上記は1からnまでの総和を求める再起関数であり、`n=5`の場合、処理のイメージとしては以下になる。<br>

- `n = 0` (`result = 0`)
    - `1 + saiki(1-1)` (`result = 1`)
        - `2 + saiki(2-1)` (`result = 3`)
            - `3 + saiki(3-1)` (`result = 6`)
                - `4 + saiki(4-1)` (`result = 10`)
                    - `5 + saiki(5-1)` (`result = 15`)

上記を反転したものが`5 + saiki(5-1)`中で行われており、`saiki(5-1)`中に`n = 4`以下の処理が含まれている。
### 使用例
#### 例題
`[1,[2,[3,[4,[5,6]]]]]`の様な多次元配列の総和を出力したい場合...

```python:
multi_list = [1,[2,[3,[4,[5,6]]]]]
def multi_sum(lis):
    result = 0
    for i in lis:
        if  type(i) == int:
            result += i
        else:
            result += multi_sum(i)
    return result
multi_sum(multi_list)
```
### 参考
ほぼほぼ以下らを纏めただけ...
- [Pythonで理解する再帰関数](https://qiita.com/dhirabayashi/items/2f079e62fa2e286f1766)
- [【Python】再帰関数をシンプルな例題で理解する](https://engineeeer.com/recursive-function-python/)

# 36.グラフのリアルタイム描画
```python:
import matplotlib.pyplot as plt
import numpy as np
import random
from numpy.random import rand

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

ax.set_xlim((-1,100))

x = []
y = [random.random() for i in range(100)]

count = 0
while True:
    x.append(count)
    line, = ax.plot(x, y[0:count+1], color='blue')
    count += 1
    plt.pause(0.1)

    if count == 99:
        break
    else:
        line.remove()
```

# 37.グラフのリアルタイム描画2
データ量が多いと描画速度が遅すぎるので、スキップするフレームを設定して設定フレーム毎に出力する。
```python:
fig, ax = plt.subplots(1, 1)

x = x軸のデータ
y = y軸のデータ
min_is = min(y)
max_is = max(y)

xll = [-1,len(x)+1]
yll = [min_is-margin,max_is+margin]

xyl = {"x":[],"y":[]}だとする
skip_frame = 5
def update(frame):
    if frame%skip_frame == 0:
        # start_time = time.perf_counter()
        # 一旦ax.cla()でリセット、xlim ylimもリセットされるので定義し直す
        ax.cla()
        ax.set_xlim(xll)
        ax.set_ylim(yll)
        xyl["x"].append(x[frame])
        xyl["y"].append(y[frame])
        ax.plot(xyl["x"], xyl["y"])
        # endi = str(time.perf_counter() - start_time)
        # print('\rtime= %s' % endi, end='')
    # 設定されたフレーム以外はデータを蓄積する
    elif not frame == len(x)-1:
        xyl["x"].append(x[frame])
        xyl["y"].append(y[frame])
    else:
        plt.close()
count = 0

# fig, 描画する関数, 何フレーム描画するか, どれぐらいの間隔で描画するか
anim = FuncAnimation(fig, update, frames=range(len(x)), interval=1)
plt.show()
```

# 38.標準入力の高速化
```python:
import sys
input = sys.stdin.readline
# これで普通にinput()を使う
```