3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python備忘録

Last updated at Posted at 2019-04-29

何度も使うのに正確な書き方忘れてしまう内容リスト

よく使うライブラリの略称

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)  #末端ディレクトリが既に存在していても構わずディレクトリを作成する

ファイルを読み取り専用で開いてリストに格納

version1.py
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)
version2.py
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がいるかどうか確認できる。具体的には

check_class_member.py
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.pymodule2.pyをimportしたい場合は

from dir1 import module1
from dir1.dir2 import module2

Python で別ファイルの import

/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が代入されている。

hoge.py
if not __debug__ :
    some_debug_procedure()

としておくと、python3 -O hoge.pyとしたときだけ、some_debug_procedre()が呼ばれる。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?