map(), filter()
pythonのmap(), filter()の使い方について。
map()
Definition : map(func, *iterables)
リストなどの全要素に関数を適用し、イテレータを作る。
もとのリストは保存され、非破壊的。
mapオブジェクトを生成するので、中身を見たければlist化など。
list1 = [1.7, 5.9, -3.68] m = map(int, list1) print(m) # <map object at 0x...> print(list(m)) # [1, 5, -3]
mapのかわりに内包表記でも書ける
list1 = [1.7, 5.9, -3.68] print([int(i) for i in list1]) # [1, 5, -3]
mapオブジェクトはイテレータ
list1 = [1.7, 5.9, -3.68] m = map(int, list1) print(next(m)) # 1 print(next(m)) # 5 print(next(m)) # -3
lambda関数も使える
m = map(lambda x:x**2, range(4)) print(list(m)) # [0, 1, 4, 9]
map()を使って相関係数を計算する
公式:
# correlation coefficient def corr(x, y): if len(x) != len(y): return "different length" sx = sum(x) sy = sum(y) sx2 = sum(map(lambda x:x**2, x)) sy2 = sum(map(lambda x:x**2, y)) sxy = sum(map((lambda x, y:x*y), x, y)) n = len(x) try: return (n*sxy-sx*sy)/((n*sx2-sx**2)*(n*sy2-sy**2))**0.5 except: return 0 x = [1, 2, 3] y = [5, 5, 6] print("相関係数:", corr(x, y)) # 相関係数: 0.8660254037844387
filter()
Definition : filter(function or None, iterable)
リストなどの全要素に関数を適用し、Trueのものだけのイテレータを作る。
もとのリストは保存され、非破壊的。
filterオブジェクトを生成するので、中身を見たければlist化など。
正の要素だけ選ぶ
list1 = [1.7, 5.9, -3.68] f = filter(lambda x:x>0, list1) print(list(f)) # [1.7, 5.9]
内包表記でも書ける
list1 = [1.7, 5.9, -3.68] f = filter(lambda x:x>0, list1) print(list(f)) # [1.7, 5.9]
関数をNoneにすると、Trueのものだけを選ぶ。
f = filter(None, range(4)) print(f) # <filter object at 0x...> print(list(f)) # [1, 2, 3]
filter()とは逆に偽の要素を選ぶ関数としてitertools.filterfalse()がある。
バーンスレイのシダ
○バーンスレイのシダ
4種類の変換をそれぞれ、85%、7%、7%、1%の確率で選んでいきます。
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt def transform1(p): x, y = p[0], p[1] x1 = 0.85*x + 0.04*y y1 = -0.04*x + 0.85*y + 1.6 return x1, y1 def transform2(p): x, y = p[0], p[1] x1 = 0.2*x - 0.26*y y1 = 0.23*x + 0.22*y + 1.6 return x1, y1 def transform3(p): x, y = p[0], p[1] x1 = -0.15*x + 0.28*y y1 = 0.26*x + 0.24*y + 0.44 return x1, y1 def transform4(p): y = p[1] x1 = 0 y1 = 0.16*y return x1, y1 def transform(p): transforms =[transform1, transform2, transform3, transform4] # 0~3の中から、85%, 7%, 7%, 1%の重みでインデックスを選ぶ index = np.random.choice([0, 1, 2, 3], p=probability) t = transforms[index] x, y = t(p) return x, y def draw(n): x, y = [0], [0] # x、yはn個の要素を持つリストになる x1, y1 = 0, 0 # 現在の座標 for i in range(n): x1, y1 = transform((x1, y1)) x.append(x1) y.append(y1) return x, y n = 1000 # 点の数 # 85%, 7%, 7%, 1% probability = [0.85, 0.07, 0.07, 0.01] # 合計が1.00 x, y = draw(n) plt.plot(x, y, "o", c="g", markeredgecolor="darkgreen") plt.title("Fern with {} points".format(n)) plt.show()
n=1000として、1000個の点で描いたシダ
n=8000として、8000個の点で描いたシダ
参考:
Pythonからはじめる数学入門 Amit Saha
matplotlibでアニメーション
matplotlibでアニメーションを作ります。
# -*- coding: utf-8 -*- import matplotlib.pyplot as plt import matplotlib.animation as ani def create_circle(): c1 = plt.Circle((0, 0), 0.5) return c1 def update_radius(i, c1): # i:フレーム番号 plt.cla() c1.radius = i*0.5 # 最大半径15 return c1, def create_animation(): fig = plt.gcf() ax = plt.axes(xlim=(-10, 10), ylim=(-10, 10)) ax.set_aspect("equal") c1 = create_circle() ax.add_patch(c1) anim = ani.FuncAnimation(fig, update_radius, fargs=(c1,), frames=30, interval=50) anim.save("circle.gif", writer = 'imagemagick') create_animation()
円が徐々に大きくなるアニメーションになるはずが、
ValueError: Cannot save animation: no writers are available. Please install ffmpeg to save animations.
というエラーが出てうまくいきませんでした。
imagemagickをダウンロードして、matplotlibrcのanimation convert pathを
#animation.convert_path: C:\py3531\pytemp\ImageMagick-7.0.5-5-portable-Q16-x86\magick.exeとしましたが認識せず。
また時間のある時にでも調べてみます。
matplotlibで図形
matplotlibで図形を描く方法。
plot()関数が呼ばれると背後でfigure()が呼ばれ、続いてaxes()が呼ばれてfigureの中に軸をつくる。
plot()関数を呼ばずにfigure()やaxes()で図、軸を設定できる。
import matplotlib.pyplot as plt c1 = plt.Circle((0, 0), radius=1, fc="yellow", ec="r") ax = plt.gca() ax.add_patch(c1) plt.axis("scaled") plt.show()
○figure()関数
Figureオブジェクトを作る。
Definition :
figure(num=None, # autoincrement if None, else integer from 1-N figsize=None, # defaults to rc figure.figsize dpi=None, # defaults to rc figure.dpi facecolor=None, # defaults to rc figure.facecolor edgecolor=None, # defaults to rc figure.edgecolor frameon=True, FigureClass=Figure, **kwargs)
num | figure番号。整数または文字列のオプション引数でデフォルトはNone。もしnumが与えられなければ、新しいfigureを作り、figure番号を1増やす。figureオブジェクトはこの番号をnumber属性として保持する。もしnumが与えられ、すでに存在しているfigure番号だった場合は、そのfigureオブジェクトをアクティブにし、参照を返す。存在しないfigure番号のときは、新規のfigureオブジェクトを作成し、その参照を返す。numが文字列のときはウィンドウのタイトルがnumになる。 |
---|---|
figsize | (幅, 高さ)の整数のタプルで単位はインチ。デフォルトはrc figure.figsize |
dpi | figureの解像度。整数で、デフォルトははrc figure.dpi |
facecolor | 背景色。デフォルトはrc figure.facecolor |
edgecolor | 枠の色。デフォルトはrc figure.edgecolor |
返り値 | figureオブジェクト |
---|
○axes()関数
Figureオブジェクトに座標軸を付け加える
parameter | 値 | 内容 |
---|---|---|
facecolor | color | 軸の背景色 |
frameon | True or False | 枠を表示するか |
sharex | otherax | 他の軸とxaxis属性を共有するか |
sharey | otherax | 他の軸とyaxis属性を共有するか |
polar | True, False | 極座標を使うか |
aspect | "equal", "auto", num | アスペクト比x/y。"equal"は1:1 |
○axis()メソッド
要素数4のタプルを引数としてaxis()メソッドを呼ぶと、座標軸の範囲を変更できる。
引数 | 内容 |
---|---|
なし | 現在の座標軸の範囲を(xmin, xmax, ymin, ymax)のタプルで返す。 |
"off" | 座標軸を表示しない |
"equal" | 円が円に見える。 |
"scaled" | 座上軸の両端の自動調整 |
"tight" | 余白を小さく? |
"image" | データの範囲に合わせる |
"auto" | 非推奨 |
"normal" | 非推奨 |
"square" | x軸の範囲(xmax-xmin)とy軸の範囲を等しくする |
fig = plt.figure() ax =plt.axes() print(plt.axis()) # (0.0, 1.0, 0.0, 1.0) v = (0, 2, 0, 3) plt.axis(v) plt.show()
x軸の範囲が0~2、y軸の範囲が0~3になっている。
gcf()関数:現在のFifureへの参照。オブジェクトがない場合は作成する。
gca()関数:現在のAxesへの参照。オブジェクトがない場合は作成する。
○ax.set_aspect()関数
グラフのアスペクト比を設定する。
○円plt.Circle以外にもいろいろな図形が書ける。
Ellipse, Polygon, Rectangleなどなど
参考:
patches — Matplotlib 2.0.1 documentation
csvライブラリ
csvモジュールの使い方について。
以下の内容のtest.csvを準備しました。
1,20 2,30 3,40 4,50
○csvファイルの読み取り
(1)各行はリストとして読み込まれる。
import csv with open("test.csv", "r") as f: data = csv.reader(f) print(data) <_csv.reader object at 0x...> for i in data: # 各行がリストになっている print(i) # ['1', '20'] # ['2', '30'] # ['3', '40'] # ['4', '50']
(2)joinで見やすく。
with open("test.csv", "r") as f: data = csv.reader(f) print(data) for i in data: print(", ".join(i)) # 1, 20 # 2, 30 # 3, 40 # 4, 50
csv.reader()の引数になるのは、ファイルオブジェクトまたはリスト
(3)読み飛ばしたい行があるときはnext()する。
with open("test.csv", "r") as f: data = csv.reader(f) next(data) # 1行読み飛ばす for i in data: print(", ".join(i)) # 2, 30 # 3, 40 # 4, 50
(4)読み飛ばす行をヘッダーなどとして使用するときは代入をしておく。
with open("test.csv", "r") as f: data = csv.reader(f) header = next(data) # 1行読み飛ばし、headerに代入 print(header) # ['1', '20'] for i in data: print(", ".join(i)) # 2, 30 # 3, 40 # 4, 50
○csvファイルの書き込み
newline=""とオプションを入れないと、空白行が追加されてしまう。
(1)
import csv with open('test.csv', 'w', newline="") as f: writer = csv.writer(f) writer.writerow([1] + [20]) writer.writerow([2, 30]) for i in range(3, 5): writer.writerow([i, (i + 1) * 10])
(2)
data =[[1, 20], [2, 30], [3, 40], [4, 50]] with open('test.csv', 'w', newline="") as f: writer = csv.writer(f) writer.writerows(data)
matplotlibの色名一覧
この色名一覧はpythonで書かれていて、同じページにコードも載っています。
あとでゆっくりコードを読んでみようと思います。
# coding: utf-8 from __future__ import division import matplotlib.pyplot as plt from matplotlib import colors as mcolors colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS) # (HSV形式,色名)というタプルに直し、Hをキーにしてソートしたリストにする by_hsv = sorted((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name) for name, color in colors.items()) # sortしたタプルのリストから、色名だけを抜き出したリストを作る sorted_names = [name for hsv, name in by_hsv] n = len(sorted_names) # 8色 + 148色 = 全156色 ncols = 4 # 列数を4にする。他の数でもよい nrows = n // ncols + 1 # 行数を計算 fig, ax = plt.subplots(figsize=(8, 5)) # 横8インチ、縦5インチ # Get height and width X, Y = fig.get_dpi() * fig.get_size_inches() h = Y / (nrows + 1) # 1マスの縦のドット数 w = X / ncols # 1マスの横のドット数 for i, name in enumerate(sorted_names): col = i % ncols # 0番 1番 2番 3番 row = i // ncols # 4番 5番 6番 7番 ...のように割り振る y = Y - (row * h) - h # 表示するy座標 xi_line = w * (col + 0.05) # 長方形の左端のx座標 xf_line = w * (col + 0.25) # 長方形の右端のx座標 xi_text = w * (col + 0.3) # 色名の文字列を表示するx座標 # 左よせで文字を表示 ax.text(xi_text, y, name, fontsize=(h * 0.8), horizontalalignment='left', verticalalignment='center') # hlines(横向きの直線)として色つきの長方形を表示 ax.hlines(y + h * 0.1, xi_line, xf_line, color=colors[name], linewidth=(h * 0.6)) ax.set_xlim(0, X) ax.set_ylim(0, Y) ax.set_axis_off() fig.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0) plt.show()
わからないことが多すぎるので、いろいろ確認してみた。
・mcolors.BASE_COLORS :
8つの基本色。アルファベット1文字で表す。
色名:RGBの辞書型になっている。
print(mcolors.BASE_COLORS) # {'y': (0.75, 0.75, 0), 'm': (0.75, 0, 0.75), 'r': (1, 0, 0), # 'c': (0, 0.75, 0.75), 'k': (0, 0, 0), 'g': (0, 0.5, 0), # 'w': (1, 1, 1), 'b': (0, 0, 1)}
・mcolors.CSS4_COLORS
148色の(色名:16進コード)の辞書型
print(len(mcolors.CSS4_COLORS)) # 148 print(mcolors.CSS4_COLORS) # {'oldlace': '#FDF5E6', 'limegreen': '#32CD32', 'palevioletred': '#DB7093', # 'mintcream': '#F5FFFA', 'rosybrown': '#BC8F8F', 'blueviolet': '#8A2BE2', # 'lime': '#00FF00', 'orange': '#FFA500', 'mediumorchid': '#BA55D3', ...
参考:
color example code: named_colors.py — Matplotlib 2.0.1 documentation
matplotlibで散布図
matplotlibで散布図を描く方法について。
Definition :
plt.scatter( x, y, # x座標, y座標の配列 s=None, # マーカーのサイズ c=None, # マーカーの色 marker=None, # マーカーの形 cmap=None, # cがfloat型のときのカラーマップ norm=None, # cをfloat型配列にした時の規格化インスタンス指定 vmin=None, vmax=None, # 最大・最小 alpha=None, # 透明度 linewidths=None, # 線の太さ verts=None, edgecolors=None, # 線の色 hold=None, data=None, **kwargs)
色名一覧はここ
・乱数で100個の点を描く
import numpy as np import matplotlib.pyplot as plt x = np.random.rand(100) y = np.random.rand(100) plt.scatter(x, y) plt.show()
・マーカーをひし形にして、色を付ける。
x = np.random.rand(100) y = np.random.rand(100) plt.scatter(x, y, s=100, c="orange", edgecolor="red") plt.show()
・直線、軸、タイトルつき。
import numpy as np import matplotlib.pyplot as plt #日本語を使う場合は以下の2行でフォントを準備 from matplotlib.font_manager import FontProperties fp = FontProperties(fname='C:\WINDOWS\Fonts\msgothic.ttc', size=14) x = np.arange(20) y = x + np.random.rand(20)*4 plt.scatter(x, y, s=50, marker="x", c="red", linewidth=1) plt.plot([0, 19], [2, 21], c="blue") #直線の描画 plt.title("散布図", fontproperties=fp) plt.xlabel("x軸", fontproperties=fp) plt.ylabel("y軸", fontproperties=fp) plt.show()
chars = "^<>vo+d" x = np.random.rand(100) y = np.random.rand(100) markers = [chars[i%7] for i in range(100)] for i in range(100): plt.scatter(x[i], y[i], marker=markers[i]) plt.show()
x = np.random.rand(10000) y = np.random.randn(10000) plt.scatter(x, y, alpha=0.2) plt.show()
x = np.random.randn(10000) y = np.random.randn(10000) plt.scatter(x, y, alpha=0.2) plt.show()
カラーマップを使う。
x = np.random.rand(100) y = np.random.rand(100) col = np.linspace(0, 1, 100) plt.scatter(x, y, c=col, cmap="spring") plt.colorbar() #カラーバーの表示 plt.show()
カラーマップの一覧はここに。
参考: