何度も使うのに正確な書き方忘れてしまう内容リスト
よく使うライブラリの略称
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pymatgen as mg
コマンドラインオプション
python3 -O # __dubug__ にFalseを代入
python3 -u # stdout, stderrをバッファしない
システムコマンド
IPython, Jupyterにおいて、システムのコマンドを!
に引き続いて書くことで実行できる。
Jupyter Notebookでシステムコマンドを実行し文字列のリストとして取得 | note.nkmk.me
例えば、
!python ./test.py > log.log
とすると、jupyter上でも、test.py
を実行して、その標準出力をファイルにリダイレクトできる。
マジックコマンドで%run ./test.py > log.log
だと、こうした挙動にはならない
ディレクトリの作成
import os
dir_path = 'path/4/directory/you/wanna/make'
os.mkdir(dir_path) #末端ディレクトリの親ディレクトリを自動生成しない
os.makedirs(dir_path) #末端ディレクトリの親ディレクトリを自動生成する
os.makedirs(dir_path, exist_ok=True) #末端ディレクトリが既に存在していても構わずディレクトリを作成する
ファイルを読み取り専用で開いてリストに格納
fname = 'file_name_to_be_opened_including_path'
f = open(fname,'r')
lines = f.readlines()
f.close()
Nlen = len(lines)
print(Nlen, ': No. of lines of the file, ',fname)
fname = 'file_name_to_be_opened_including_path'
with open(fname, 'r') as f: #withを使うとcloseまでセット
lines = f.readlines()
Nlen = len(lines)
print(Nlen, ': No. of lines of the file, ',fname)
readlines
で読み込んだデータを配列に格納
array1 = np.zeros(Nlen,dtype='int')
array2 = np.zeros(Nlen,dtype='float64')
array1 = np.zeros(Nlen,dtype='float64')
for i in range(Nlen):
temp = lines[i].split() #スペース区切りで文字列をリストに
array1[i] = np.int(temp[0])
array2[i] = np.float(temp[1])
array3[i] = np.float(temp[2])
ファイルの書き出し
fname = 'file_name_to_be_opened_including_path'
f = open(fname,'x')
#f = open(fname,'w')
temp = 'Characters to be written.'
f.write(temp)
f.close()
浮動小数点を適当な桁数の文字列に変換
str1 = '{:.5f}'.format(float1) #小数点以下5桁の文字列に変換
参考: 【Python】formatを用いた書式設定の基本 | Hbk project
ランダムなUUIDを生成
import uuid
uuid.uuid4() #ランダムなUUIS
temp = str(uuid.uuid4()) #文字列に変換
辞書 (dict class)
val1 = "hoge"
val2 = 2
val3 = 0.0+1.0j
d = {'key1': val1, 'key2': val2}
d.update({'key3': val3}) # 追加
print(type(d))
print(len(d))
print(d.keys()) # キーのみ出力
print(d.values()) # 値のみ出力
#
for k in d.keys():
print(d[k], type(d[k]))
list(d.keys()) # dict_keys を listへ変換
#dit_keysはlistにせずとも、そのままで for k in d.keys() とすれば、動く
value = d['key1'] # value に val1を代入
print(value, type(value))
JSON
辞書クラスには複素数の変数が入っていてもいいが、JSONに変換しようとすると、エラーで止まるのでちゅうい。
import json
val1 = "hoge"
val2 = 2
d = {'key1': val1, 'key2': val2} # 辞書クラスを定義
d_str = json.dumps(d) #辞書 d をstringに変換
print(d_str)
f = open('test_json.json',"w")
json.dump(d, f, indent=2) #辞書 d を"test_json.json"にインデント2文字で書き込む
f.close()
f = open('test_json.json', "r")
d2 = json.load(f) #ファイル"test_json.json"に記載された内容を辞書 d2 にかくn
f.close()
classの定義
はじめに — pep8-ja 1.0 ドキュメントによると、
クラスの名前には通常 CapWords 方式を使うべきです。
class MyClass:
"""Explanation of this class"""
variable = 'hogehoge'
def __init__(self, val = 0.1):
self.a = 'hoge'
self.b = 10
self.c = 1.0e2
self.d = np.zeros(self.b)
self.val = 1.0*val
def func1(self):
v = self.b + 1
self.b += 1
return v
def func2(self,x):
v = self.c + x
self.c += x
return v
MC = MyClass(val = 0.2)
print(MC.variable)
print(MC.a)
print(MC.func1())
print(MC.func2(2.0))
print(MC.d)
他のclassを継承
class MyClass(AnotherClass):
classの中身を確認
import inspect
MC = MyClass()
members = inspect.getmembers(MC)
for a in members:
print(a)
変数の代入しそびれの回避
Classで、変数の初期値をNone
にしておけば、上記のclassメンバーの確認をすることで、メンバーにNone
がいるかどうか確認できる。具体的には
import inspect
members = inspect.getmembers(data)
for a in members:
if (a[1] is None):
print(a)
で、メンバーがNone
になっているものは出力される。
@property
を使ったクラス内変数の処理
まだきちんと理解していない。
「関数型プログラミング」と「オブジェクト指向」ってなんやねんPython編 - Qiita
python property - Qiita
@classmethod
クラスメソッド
クラスからメソッドを呼び出すときはMyClass.func1()
として呼び出すことはできず、MC = MyClass
としてインスタンスにしてからMC.func1()
として呼び出す。@classmethod
のデコレーターを使うことで、MyClass.func1()
のように呼び出すことができるようになる。
Pythonのクラスメソッド(class method)の定義の仕方とstaticmethodとの違い - St_Hakky’s blog
listの操作
l = [] #空list, lの宣言
l.append(hoge) #lに要素 hoge を追加
Numpy関数
import numpy as np
np.arange(xs,xe,dx)
np.linspace(xs,xe,Nx)
np.linspace(xs,xe,Nx,endpoint = True)
np.round(real_value,2) #real_valueを小数点以下2桁で丸める
np.append(a,b) #aにbを追加したarrayを生成
np.array([ [0.0, 1.0, 2.0] , [3.0, 4.0, 5.0]]) #2x3のnumpy arrayの生成
np.array(some_list) #リストsome_listをnumpy arrayに変換
np.argmax(x) # xの最大値を与える引数を返す
np.random.seed(seed=123) #np.randomのシードを123に固定
np.random.rand(10) #乱数を成分に持つ要素数10の一次元numpy array
np.random.rand(10, 20) #乱数を成分に持つ10x20のnumpy array
np.clip(x, minval, maxval) #array xの値をminvalからmaxvalに制限したarrayをかえす。minval, maxalのどちらかを指定したくない場合は None にする
np.where(np.abs(x)<0.1, 0.0, x) #array xの絶対値が0.1よりも小さいときは0にし、そうでないときはそのままxの要素を返す関す
np.append(a,b, axis=0) #二次元配列aの列方向右に二次元bを追加
np.append(a,b, axis=1) #二次元配列aの行方向下に二次元bを追加
numpy array (a1[n,m,1])を(a2[n,m])にしたい場合
a2 = a1[:,:,0]
numpy arrayの部分配列の切り取り方
[n,m]の配列aについて
b = a[n, 0] #一次元配列になる
b = a[n, 0:1] #[n,1]の二次元配列になる
save
/load
# tt, Jtを filename に保存
np.savez('filename', tt=tt, Jt=Jt) #複数のndarrayを一つのファイルに保存するときはsavez関数
# tt, Jtを filename から読込
temp = np.load('filename')
print(temp.files) # ['tt', 'Jt']
tt = temp['tt']
Jt = temp['Jt']
fft
Discrete Fourier Transform (numpy.fft) — NumPy v1.24 Manual
t = np.arange(0.0, tend, dt)
ft = f(t)
# dt = t[1] - t[0]
Nt = len(t)
omega = np.fft.fftfreq(NT)*(2.0*np.pi/dt)
fF = np.fft.fft(ft)
$$
A_k = \sum_{m=0}^{n-1}a_m \exp \left( -2\pi \mathrm{i} \frac{mk}{n} \right) \\
a_m = \frac{1}{n}\sum_{k=0}^{n-1}A_k \exp \left( +2\pi \mathrm{i} \frac{mk}{n} \right)
$$
$\sum_{k=0}^{n-1} \left| A_k \right|^2 = n\sum_{m=0}^{n-1} \left| a_m \right|^2$
Scipyの呼び方
例えばscipy.special.ellipk
を呼びたいとき
from scipy import special
hogehoge = special.ellipk(hoge)
あるいは
from scipy.special import ellipk
hogehoge = ellipk(hoge)
matplotlib
いろんなAPIのプロット例: matplotlibのpyplot APIをいろいろ試す - そうなんでげす
matplotlibでグリッドをつけてプロット
import matplotlib.pyplot as plt
plt.figure()
plt.xlabel('hoge',fontsize = 18)
plt.ylabel('hoge',fontsize = 18)
plt.xticks(fontsize = 18)
plt.yticks(fontsize = 18)
plt.plot(x,y,label='label',linewidth = 3.0)
plt.grid()
plt.legend(fontsize = 18)
plt.savefig("output.pdf")
plt.show()
plt.plot(x,y, 'o') # plot w/ points
plt.plot(x,y, 'o', linestyle='solid') # plot w/ line-points
plt.fill_between(x,y1,y2,facecolor='k',alpha=0.25,label='label')
plt.fill_between(x,np.amin(y)*np.ones(len(y)),y,facecolor='k',alpha=0.25,label='label')
plt.quiver(x,y,dx,dy) #ベクトル場 plt.arrowよりもこちらの方が向いている
plt.scatter(x,y) #散布図
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') #凡例を描画領域の外に出せる
plt.xlim(left=0.0,right=1.0)
plt.ylim(bottom=0.0,top=1.0)
plt.axis('scaled') #グラフの縦横の長さをそろえる
plt.axis('off') #軸を消す
plt.gca().set_aspect('equal', adjustable='box') #https://qiita.com/show2214/items/064c671709dda08d78c8
plt.title('(a)', loc='left',fontsize = 24, x=-0.2, y=1.00) #図に(a)とか(b)をつける
Matplotlibで出力するPDFの下のほうが切れてしまうときは bbox_inches='tight' - Scala日記
plt.savefig("output.png", bbox_inches="tight")
contourf
をjetカラーマップでプロット
import matplotlib.pyplot as plt
plt.figure()
plt.contourf(x, y, 2Ddata, cmap=plt.cm.jet)
plt.colorbar()
plt.show()
import matplotlib.pyplot as plt
from matplotlib import cm, colors
Nlevel = 41 #レベルの分割数
minval = 1.0e-9
maxval = 1.0e-1
lev_exp = np.linspace(np.floor(np.log10(np.abs(minval)) ), np.ceil(np.log10(np.abs(maxval)) ), Nlevel)
levs = np.power(10, lev_exp)
plt.contourf(x, y, 2Ddata, levs, norm=colors.LogNorm(), cmap=plt.cm.jet)
plt.colorbar()
plt.show()
2次元プロット用グリッド生成
nx, ny = (30, 20)
x = np.linspace(-2, 2, nx)
y = np.linspace(-1, 1, ny)
x2D, y2D = np.meshgrid(x, y, indexing="ij") #indexingを"xy"にすると形状が転置される
print(nx, ny)
print(x.shape, y.shape)
#print(x,y)
print(x2D.shape, y2D.shape)
#print(x2D, y2D)
import matplotlib.pyplot as plt
plt.show()
plt.figure()
plt.contourf(x2D, y2D, x2D**2+y2D**2, cmap=plt.cm.jet)
plt.colorbar()
plt.gca().set_aspect('equal', adjustable='box') #https://qiita.com/show2214/items/064c671709dda08d78c8
plt.show()
matshow
import matplotlib.pyplot as plt
plt.matshow(2Darray,cmap=plt.cm.jet)
plt.colorbar()
plt.show()
三次元のプロット
三次元ベクトルal
で決まる直方体のプロット。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
al = np.zeros(3, dtype='float64')
al[0] = 1.0
al[1] = 2.0
al[2] ~ 3.0
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot([0.0, al[0]],[0.0, 0.0],[0.0, 0.0],'k--')
ax.plot([0.0, 0.0],[0.0, al[1]],[0.0, 0.0],'k--')
ax.plot([0.0, 0.0],[0.0, 0.0],[0.0, al[2]],'k--')
ax.plot([0.0, al[0]],[al[1],al[1]],[0.0, 0.0],'k--')
ax.plot([0.0, 0.0],[0.0, al[1]],[al[2],al[2]],'k--')
ax.plot([al[0], al[0]],[0.0, 0.0],[0.0, al[2]],'k--')
ax.plot([0.0, al[0]],[0.0, 0.0],[al[2],al[2]],'k--')
ax.plot([al[0], al[0]],[0.0, al[1]],[0.0, 0.0],'k--')
ax.plot([al[0], al[0]],[0.0, 0.0],[0.0, al[2]],'k--')
ax.plot([0.0, 0.0],[al[1],al[1]],[0.0, al[2]],'k--')
ax.plot([0.0, al[0]],[al[1],al[1]],[al[2],al[2]],'k--')
ax.plot([al[0], al[0]],[0.0, al[1]],[al[2],al[2]],'k--')
ax.plot([al[0], al[0]],[al[1],al[1]],[0.0, al[2]],'k--')
ax.axis('equal')
plt.show()
数式のフォントにComputer Modernを使いたい
フォント自体は以下からダウンロードできる
Using Computer Modern on the web
フォント周りのコマンド
# 関連pathの表示
import matplotlib
matplotlib.matplotlib_fname()
## 使えるフォントリストの表示
import matplotlib.font_manager as fm
import pprint
font_list = [f.name for f in fm.fontManager.ttflist]
pprint.pprint(font_list)
Path
コードの中でpathを追記したい場合
import os
import sys
import pprint
sys.path.append(os.path.dirname('/path/to/be/added'))
pprint.pprint(sys.path) #Pathの確認
環境変数で追記したい場合
export PYTHONPATH=/path/to/be/added:$PYTHONPATH
module
.
├── dir1/
│ ├── dir2/
│ │ └── module2.py
│ └── module1.py
└── main.py # <= 呼び出し側
のmodule1.py
とmodule2.py
をimportしたい場合は
from dir1 import module1
from dir1.dir2 import module2
/some/path/module3.py
を呼びたいとき
import sys
sys.path.append('/some/path')
from path import module3
moduleのreload
コードの開発時、デバッグ時にはモジュールも変更してその挙動を確認したい。
一方、デフォルトではimport my_module
で、moduleを読み込むと、ipythonやjupyter上ではメモリ上に確保されて、my_module.py
の変更を反映しない。この変更分を反映させるための方法。
コードの中でインタラクティブにリロード
この変更を反映させるためにはimportlib
を使う
import importlib
importlib.relaod(my_module)
で、my_module.py
の変更を反映。
引数はモジュールでないとだめで、個別の関数等は引数にとれない。例えばfrom my_module import my_func
のようにして、my_func
をインポートしていて、my_module
をインポートしていない場合には相性が悪い。その時は、ipython, jupyter notebookを使っている場合は、以下の方法をつかう。
マジックコマンドで挙動を指定(ipython, jupyter notebook)
以下のマジックコマンドを付けておけば、モジュールは%run *.py
で実行毎に読み込まれる。コードの開発時用。
%load_ext autoreload
%autoreload 2
ipython を起動しながら自作モジュールを修正した場合 - Qiita
__init__.py
の役目
なんだか、小難しい。要再勉強。
Python の init.py とは何なのか - Qiita
module間で変数や関数を共有
config.py
のようなものを作って、他のmoduleからはこれをimport config
で呼ぶ。
プログラミング FAQ — Python 3.8.2 ドキュメント
時間計測
import time
ts = time.time()
te = time.time()
elapse_time = te - ts # in sec.
単位変換リスト
import sys
import numpy as np
import math
import matplotlib.pyplot as plt
#Mathematical constants
pi = np.pi
tpi = 2.0*pi
fpi = 4.0*pi
zI = 1.0j
#Physical constants
#https://ja.wikipedia.org/wiki/%E5%8E%9F%E5%AD%90%E5%8D%98%E4%BD%8D%E7%B3%BB
Bohr2nm = 0.0529177210903 #nanometer
Hartree2eV = 27.211386245988 #eV
Atime2fs = 0.024188843265857 #fs
Afield2Vpnm = Hartree2eV/Bohr2nm #V/nm
Avolume2nm3 = Bohr2nm**3 #nm^3
#https://ja.wikipedia.org/wiki/%E5%BE%AE%E7%B4%B0%E6%A7%8B%E9%80%A0%E5%AE%9A%E6%95%B0
sol = 137.035999084 #speed of light
ch_eVnm = 1241.5 #eV * nm
chbar_eVnm = 197.3 # eV * nm
halfepsc_Aunit2Wpcm2 = 3.509e16 # W/cm^2 \frac{1}{2}*\epsilon_0 * c
Afluence2Jpcm2 = halfepsc_Aunit2Wpcm2*Atime2fs*1.0e-15 # J/cm^2 ,W/cm^2 * fs = femto J/cm^2
一度代入した変数に再代入しようとすると停止するプログラム
定数用のclassを用意して、二回目の代入でシステムを停止する処理を記載する。
Python で定数を定義する | まくまくPythonノート
Jupyter
jupyter notebook --port 8888 #Jupyter notebook をport番号8888で開く
pip
pip install pymatgen
pip install pymatgen==2020.10.20 #バージョンの指定
pip list #インストールされたもののリストを表示
pip freeze #pip listに近いやつ
デバッグあれこれ
組み込み定数 __debug__
コード内の__debug__
はpython3 -O hoge.py
ではFalse
が代入されて、通常の実行ではTrue
が代入されている。
if not __debug__ :
some_debug_procedure()
としておくと、python3 -O hoge.py
としたときだけ、some_debug_procedre()
が呼ばれる。