Pythonは動的型付け言語
型宣言などはなく、型を自動で判別してくれる
演算子: +
, -
, *
, /
, //
(整数部), %
(余り), **
(べき乗)
a = 2 # 整数
b = 5.0 # 実数
c = -0.5+5j # 複素数
print(a)
print(type(a))
a = 3
b = 2
print(a**2)
print(a/b) # Python 3.xでは1.5、2.xでは1
a = (3 > 2) # True
b = (3 == 2) # False
print(a)
print(a and b)
print(a and (not b))
リストやタプルの配列要素はなんでもよい... 数、文字列、リスト
配列要素のインデックスは、原則0からN-1まで(Nが配列要素数)
ただし、-Nから-1までをインデックスに取ることもできる
len(配列)は配列要素数を返す
a = [1,3,5,7,9] # a[0], a[1], a[2], a[3], a[4]
print(a[0])
print(a[1])
print(a[-1]) # a[-1]=a[4]
print(len(a))
部分配列は、
a[start:stop]
a[start:stop:step]
などの形で得られる。部分配列にa[stop]は含まれないことに注意!
startを省略すると最初から、stopを省略すると最後まで
a = [1,3,5,7,9]
print(a[1:3]) # [a[1], a[2]]
print(a[::2])
print(a[::-1])
price = {"coffee":100, "tea":120}
print(price["tea"])
オブジェクト指向型言語であるPythonでは、ユーザーが新たな型(クラス)を定義できる
データ構造だけでなく、演算規則やさまざまなメソッドも
その中でもNumPy ndarrayが特に重要... 高機能な配列計算を提供
メソッド: 型(クラス)に固有の関数
オブジェクト名.メソッド名(引数)
の形をとる
# 文字列型のメソッド例
a = "I like tomatoes"
b = "12"
print(a.split())
print(a.upper())
print(b.zfill(4))
Fortranなどと同様に、型の名前の関数を作用させることで型変換できる
a = 100.0
b = str(a) # 実数 -> 文字列
if [論理型]:
[処理]
elif [論理型]:
[処理]
else:
[処理]
[論理型]がTrueならば[処理]を行う
elifはelse ifのこと。ifのみ、if-else、if-elif-elif-...などももちろん可
end ifにあたるものはなく、インデントによってブロックを判別している
インデントは通常スペース4つ
x = 100
if x%2 == 0:
print("x is even")
else:
print("x is odd")
x = "ABC"
for i in x:
shout = i + "!" # 文字列の「足し算」は結合
print(shout)
Fortranのdo i = start, stop, step
にあたるループを回したいときは、
for i in range(start,stop,step):
[処理]
とすればよい。range関数は、startからstopまで、step幅の等差数列を返す
stopは含まれないことに注意!
range(start,stop)なら[start, start+1, ..., stop-1]
range(stop)なら[0, 1, ..., stop-1]
for i in range(5): # i=0,1,2,3,4
print(i**3)
Fortranでいうsubroutineとfunctionは、どちらもfunctionとして扱われる
def func_name(引数):
処理
return 戻り値
returnはなくても良い
関数を呼ぶときは、
func_name(引数) # returnのない場合
x = func_name(引数) # 戻り値を代入
# 引数を3乗して返す関数
def cube(x):
return x**3
# 引数やreturnがなくても良い
def bark():
print("Bow-wow!")
y = cube(3) + cube(4) # 27 + 64 = 91
print(y)
bark()
複数のスクリプトで用いる変数や関数群をひとつの.pyファイルにまとめておき、モジュールとすることができる
# my_module.pyの中身
pi = 3.141592
def area(r):
return pi * r * r
これを別のスクリプトで使うには、import文を用いる
import my_module
radius = 5.0
S = my_module.area(radius) # my_module内のarea関数
pi = 0
print(pi) # このスクリプトの変数pi
print(my_module.pi) # my_module内の変数pi
import my_module as mm # 別名をつける
S = mm.area(1.0)
from my_module import area # モジュール内の特定のオブジェクトをインポート
S = area(1.0)
Pythonの外部ライブラリで、計算のためのさまざまな関数・定数が入っている
特に、NumPyの提供する多次元配列型NumPy ndarrayは、Pythonでの科学計算の中核となる機能である
import numpy as np # NumPyモジュールをインポート
x = np.linspace(0., 2*np.pi,100) # 0から2piまでを100等分する1次元配列
y = np.sin(x) # y = sin(x)
a = np.zeros(5)
print(a)
b = np.ones((3,3))
print(b)
c = np.arange(start, stop, step)
d = np.linspace(start, stop, num)
arangeはPython組み込みのrangeと同様
linspaceは、stepを指定する代わりに分割数numを指定
a = np.arange(0,30,3)
print(a)
b = np.linspace(0,30,3) # 端点を含む等分割
print(b)
c = np.linspace(0,30,3,endpoint=False) # 端点を含まない等分割
print(c)
a = np.arange(10)
b = 2*a + 1 # ベクトル計算が可能
c = np.exp(a) # numpy内の関数も!
a = np.ones((3,3)) # 3x3, 成分はすべて1
a[0,0] = 5 # (0,0)成分に5を代入
a[1,0:2] = 3 # (1,0)、(1,1)成分に3を代入
a[2,:] = np.arange(3) # (2,:)成分に0,1,2を代入
print(a)
axis(整数またはタプル)で指定した軸に沿って和をとる
指定しなければ全体の和を取る
mean(平均)、max(最大)、min(最小)、var(分散)、std(標準偏差)なども同様
a = np.arange(9).reshape((3,3))
print(a)
print(a.sum(0))
print(a.sum()) # a.sum((0,1))と同じ
print(a.max(0))
ndarrayをC形式で(後ろのインデックスから順に)平らにした後、shapeのタプルの形に整列する
a = np.arange(12)
print(a)
b = a.reshape((3,4))
print(b)
c = b.reshape((2,6))
print(c)
x = np.linspace(0., 2*np.pi, 100) # 0から2piまでを100等分
y = np.sin(x)
各モジュールともSciPyにより高機能なものが入っているが、こちらで十分なこともしばしば
x = np.random.rand(8) # [0.0,1.0)の一様乱数
print(x)
fx = np.fft.rfft(x)
print(fx)
ほかの多くのスクリプト言語と同様、Pythonのループは遅い
NumPyのベクトル演算機能を活かし、forループをできるだけ無くそう
%%time
x = np.linspace(0,2*np.pi,100000)
y = np.sin(x)
%%time
x = np.linspace(0,2*np.pi,100000)
y = np.zeros(100000)
for i in range(100000):
y[i] = np.sin(x[i])
サブモジュールmatplotlib.pyplotによって、Matlab風のスクリプトで可視化できる
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 20)
y = np.sin(x)
plt.plot(x, y)
plt.show()
前の例のように、xやyはNumPy ndarrayでもよい
オプション変数としては、
などなど
コンター図(contourfは塗ってくれる)
X,Yはプロットする配列Zの定義点のx座標およびy座標
X,Y = np.meshgrid(x,y,indexing='ij')
で生成できる
N(整数)を入れると、N段階でいい感じに線を引いてくれる
V(ndarrayなど)を入れると、線を引くところを自分で指定できる
カラーバーは
plt.colorbar()
の1行!
x = np.linspace(0, 4*np.pi, 60)
y = np.linspace(-2*np.pi, 0, 30)
X,Y = np.meshgrid(x, y, indexing="ij") # (Nx, Ny)型の配列をプロットする場合はindexing="ij"をつける
u = np.cos(x.reshape(60,1))*np.exp(y.reshape((1,30))) # broadcastを使って60x30のndarrayを生成
plt.contourf(X, Y, u, 40, cmap="bwr")
plt.colorbar()
plt.show()
x = np.linspace(0, 2*np.pi, 60)
ys = np.sin(x)
yc = np.cos(x)
fig = plt.figure()
ax = plt.subplot()
ax.plot(x, ys, "b-", lw=2, label="sin")
ax.plot(x, yc, "g-", lw=2, label="cos")
ax.legend(loc="upper right", fontsize=15)
ax.set_xlim(0,2*np.pi)
ax.set_xticks(np.pi * np.linspace(0,2,5))
ax.set_xlabel("$x$", size=18)
ax.set_ylim(-1.1,1.1)
ax.set_ylabel(r"$\int_0^{2\pi}\alpha dx$", size=18)
ax.tick_params(labelsize=15)
fig.tight_layout()
plt.show()
必要なライブラリ: NetCDF4, HDF4
from netCDF4 import Dataset
data = Dataset("../../../python/hs_2016010100.nc", "r", format="NETCDF4")
print(data.variables.keys())
# data.variablesにはdictionary形式でデータが格納されている。
# .keys()はdictionaryのメソッドで、dictionaryのインデックスを返してくれる
lon = data.variables["longitude"][:] # 最後の[:]をつけるとnumpy array形式で変数が得られる
lat = data.variables["latitude"][:]
Hs = data.variables["swh"][:]
必要なライブラリ: Basemap (Matplotlib toolkits)
from mpl_toolkits.basemap import Basemap
plt.figure(figsize=(8,6))
bm = Basemap(projection="cyl", # Equidistant Cylindrical projection
llcrnrlon=0, llcrnrlat=-70,
urcrnrlon=360, urcrnrlat=70)
bm.drawcoastlines(linewidth=0.25) # 海岸線
bm.drawmeridians(np.arange(0, 360, 30)) # 経線
bm.drawparallels(np.arange(-90, 90, 30)) # 緯線
# ここからはmatplotlibの「丁寧な」描き方とほぼ同じ
X, Y = np.meshgrid(lon,lat)
x, y = bm(X, Y) # X, Yはdegree単位だが、basemapで使えるように変換してくれる
# Hsの図を描く
lev = np.linspace(0, 8, 20)
bm.contourf(x, y, Hs[0,:,:], lev)
plt.show()