2021年6月27日日曜日

積み上げ棒グラフ - matplotlib - python

■インポート


import matplotlib.pyplot as plt

■積み上げ棒グラフ


・表示用データ

#-10~10
lsX = range(-10, 11)

#値1
lsY1 = range(21)

#値2
lsY2 = range(20, -1, -1)

・普通に描写する

plt.bar(lsX, lsY1)
plt.bar(lsX, lsY2)

plt.show()
 2つの棒グラフが重なって表示される

・グラフの底上げ

plt.bar(lsX, lsY1)
plt.bar(lsX, lsY2, bottom=lsY1)

plt.show()
 2つ目のグラフの buttom= に1つ目のグラフの値を指定
 グラフが値の分だけ持ち上がる

plt.bar(lsX, lsY2, bottom=lsY1)

plt.show()
 2つ目のだけ描写すると浮かんでいるのがわかる

集合棒グラフ - matplotlib - python

■インポート


import matplotlib.pyplot as plt

■集合棒グラフ


・表示用データ

#-10~10
lsX = range(-10, 11)

#値1
lsY1 = range(21)

#値2
lsY2 = range(20, -1, -1)

・普通に描写する

plt.bar(lsX, lsY1)
plt.bar(lsX, lsY2)

plt.show()
 2つの棒グラフが重なって表示される

・棒の太さを細くする

fltWidth = 0.3

plt.bar(lsX, lsY1, width=fltWidth)
plt.bar(lsX, lsY2, width=fltWidth)

plt.show()
width= で棒の太さを調整

・棒を左右にずらす

fltWidth = 0.3

#左にずらす
lsX1 = list(map(lambda a:a - fltWidth / 2, lsX))

#右にずらす
lsX2 = list(map(lambda a:a + fltWidth / 2, lsX))

plt.bar(lsX1, lsY1, width=fltWidth)
plt.bar(lsX2, lsY2, width=fltWidth)

plt.show()
 X軸の値を太さの半分だけ左右にずらす

2軸グラフ - matplotlib - python

■インポート


import matplotlib.pyplot as plt

■2軸グラフの作成


・表示用データ

#-10~10
lsX = range(-10, 11)

#-10~10の2乗
lsY1 = [a**2 for a in range(-10, 11)]

#-10~10の3乗
lsY2 = [a**3 for a in range(-10, 11)]

・axesを作成してグラフを描写

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

ax1 = fig.add_subplot()
ax1.plot(lsX, lsY1)

plt.show()
 axesを作成して1つ目のグラフを作成

・axesを追加してグラフを描写

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

ax1 = fig.add_subplot()
ax1.plot(lsX, lsY1)

ax2 = ax1.twinx()
ax2.plot(lsX, lsY2, color='orange')

plt.show()
.twinx() で作成済みのaxesに新たにaxesを追加
  追加したaxesにグラフを描写

2021年6月21日月曜日

複数のグラフ - matplotlib - python

■インポート


import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
 matplotlibの gridspec を追加でインポート
 以降の呼び出し簡略化のため「gridspec」と名前を付ける

■複数のグラフを描写


・表示用データ

#-10~10
lsX = range(-10, 11)

#-10~10の2乗
lsY = [a**2 for a in range(-10, 11)]

・下地作成

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

plt.show()
plt.figure() でインスタンス作成
tight_layout=True を指定しておくとグラフが重なって描写されるのを防ぐ
fig.suptitle() でタイトルを追加

・分割数を指定

gs = gridspec.GridSpec(3, 3)
gridspec.GridSpec(行数, 列数) で行数と列数を指定してインスタンス作成

・位置を指定してグラフを描写

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

gs = gridspec.GridSpec(3, 3)

ax1 = fig.add_subplot(gs[0, 1])
ax1.plot(lsX, lsY)
ax1.set_title('plot')

ax2 = fig.add_subplot(gs[1, 2])
ax2.bar(lsX, lsY)
ax2.set_title('bar')

ax3 = fig.add_subplot(gs[2, 0])
ax3.scatter(lsX, lsY)
ax3.set_title('scatter')

plt.show()
fig.add_subplot() で描写する位置を指定してインスタンス作成
 位置は gs[行, 列] で指定( 0 始まり)
 後はインスタンスから .plot() などでグラフを描写

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

gs = gridspec.GridSpec(3, 3)

ax1 = fig.add_subplot(gs[0:2, 0:2])
ax1.plot(lsX, lsY)
ax1.set_title('plot')

ax2 = fig.add_subplot(gs[0:2, 2])
ax2.bar(lsX, lsY)
ax2.set_title('bar')

ax3 = fig.add_subplot(gs[2, :])
ax3.scatter(lsX, lsY)
ax3.set_title('scatter')

plt.show()
gs[行, 列] は「 : 」を使って範囲を指定できる
 ※「n:m」は「n以上m未満」の範囲、「:」だけ指定すると全範囲となる

・分割範囲の大きさを比率で指定する

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

gs = gridspec.GridSpec(2, 2, height_ratios=[1, 2], width_ratios=[3, 1])

ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(lsX, lsY)
ax1.set_title('plot')

ax2 = fig.add_subplot(gs[1, 1])
ax2.bar(lsX, lsY)
ax2.set_title('bar')

plt.show()
gridspec.GridSpec()height_ratios=[] (縦方向)、 width_ratios=[] (横方向)で分割の比率を指定

■おまけ


・axesインスタンスのグラフ装飾

fig = plt.figure(tight_layout=True)
fig.suptitle('fig title')

gs = gridspec.GridSpec(1, 2)

ax1 = fig.add_subplot(gs[0, 0])
ax1.plot(lsX, lsY, color='red', label='y')
ax1.set_title('plot')
ax1.set_xlabel('x-label')
ax1.set_ylabel('y-label')
ax1.legend()
ax1.grid()

ax2 = fig.add_subplot(gs[0, 1])
ax2.bar(lsX, lsY, color='blue', label='y')
ax2.set_title('bar')
ax2.legend()
ax2.tick_params('x', labelrotation=45)
ax2.yaxis.set_ticks([])

plt.show()

2021年6月20日日曜日

グラフの装飾 - matplotlib - python

■インポート


import matplotlib.pyplot as plt
 matplotlibの pyplot をインポート
 以降の呼び出し簡略化のため「plt」と名前を付ける

■グラフの装飾


・表示用データ

#-10~10
lsX = range(-10, 11)

#-10~10の2乗
lsY1 = [a**2 for a in range(-10, 11)]

#-10~10の2乗 * 2
lsY2 = [a**2 * 2 for a in range(-10, 11)]

・色、透過率、凡例

plt.plot(lsX, lsY1, color='#ff8000', alpha=0.5, label='y1')
plt.plot(lsX, lsY2, color='#0080ff', alpha=0.5, label='y2')

plt.legend()

plt.show()
plt.plot() に属性を指定する
  ・ color= :RGBカラー(単純な色なら'red'、'green'などでも指定可)
  ・ alpha= :透過率(0.0~1.0)
  ・ label= :凡例に記述する名前
plt.legend() で凡例をグラフに追加

・タイトル、軸ラベル、グリッド

plt.plot(lsX, lsY1, color='#ff8000', alpha=0.5, label='y1')
plt.plot(lsX, lsY2, color='#0080ff', alpha=0.5, label='y2')
plt.legend()

plt.title('sample graph')
plt.xlabel('x-label')
plt.ylabel('y-label')
plt.grid()

plt.show()

・ラインスタイル

plt.plot(lsX, lsY1, color='#ff8000', alpha=0.5, label='y1', linestyle='--')
plt.plot(lsX, lsY2, color='#0080ff', alpha=0.5, label='y2', linestyle='-.')
plt.legend()

plt.title('sample graph')
plt.xlabel('x-label')
plt.ylabel('y-label')
plt.grid(alpha=0.5, linestyle=':')

plt.show()
linestyle= で線の種類を指定
  ※グリッドも同様に指定可能

・軸目盛

plt.plot(lsX, lsY1, color='#ff8000')
plt.plot(lsX, lsY2, color='#0080ff')
plt.xticks(rotation=45)
plt.yticks(rotation=90)

plt.show()
plt.xticks()plt.yticks() )に rotation= で角度を指定して目盛を回転

plt.plot(lsX, lsY1, color='#ff8000')
plt.plot(lsX, lsY2, color='#0080ff')
plt.xticks([])
plt.yticks([])

plt.show()
plt.xticks([]) とすると目盛を削除できる

簡易グラフ - matplotlib - python

■インポート


import matplotlib.pyplot as plt
 matplotlibの pyplot をインポート
 以降の呼び出し簡略化のため「plt」と名前を付ける

■簡易グラフ


・表示用データ

#-10~10
lsX = range(-10, 11)

#-10~10の2乗
lsY = [a**2 for a in range(-10, 11)]
 ※データの長さは等しくなるように

・線グラフ

plt.plot(lsX, lsY)

plt.show()
plt.plot() にX軸とY軸の値を指定
plt.show() でグラフを表示

・棒グラフ

plt.bar(lsX, lsY)

plt.show()

・散布図

plt.scatter(lsX, lsY)

plt.show()

・ヒストグラム

plt.hist(lsY)

plt.show()
plt.hist() に値を指定
  デフォルトでは自動で10区間に分割する

plt.hist(lsY, bins=20)

plt.show()
bins= に分割数を指定できる

matplotlib - python

■インストール


 コマンドプロンプトから実行
pip install matplotlib

■グラフ作成

簡易グラフ

グラフの装飾

複数のグラフ


■いろいろなグラフ

2軸グラフ

集合棒グラフ

積み上げ棒グラフ


2021年5月16日日曜日

enumerate - python

■リストのインデックスを含めた値の取得


・インデックスを含めて取得

lsA = ['a', 'b', 'c', 'd', 'e']

for index, a in enumerate(lsA):
    print(index, a)

#出力
# 0 a
# 1 b
# 2 c
# 3 d
# 4 e
forを使いインデックスと値をまとめて抜き出せる

zip - python

■複数の配列をまとめて処理


・複数の配列から一度に要素を取得

lsA = [1, 2, 3, 4, 5]
lsB = ['a', 'b', 'c', 'd', 'e']

for a, b in zip(lsA, lsB):
	print(a, b)

#出力
# 1 a
# 2 b
# 3 c
# 4 d
# 5 e
 複数のリストから同時に値を取得

lsA = [1, 2, 3, 4, 5]
lsB = ['a', 'b', 'c', 'd', 'e']
lsC = ['あ', 'い', 'う']

for a, b, c in zip(lsA, lsB, lsC):
	print(a, b, c)

#出力
# 1 a あ
# 2 b い
# 3 c う
 リストの長さが違う場合、最小の長さで実行される

・最大の長さで実行


from itertools import zip_longest
lsA = [1, 2, 3, 4, 5]
lsB = ['a', 'b', 'c', 'd', 'e']
lsC = ['あ', 'い', 'う']

for a, b, c in zip_longest(lsA, lsB, lsC):
	print(a, b, c)

#出力
# 1 a あ
# 2 b い
# 3 c う
# 4 d None
# 5 e None
itertools.zip_longest()を使うと最大の長さで実行される
 足りない値はNoneで補填される

from itertools import zip_longest
lsA = [1, 2, 3, 4, 5]
lsB = ['a', 'b', 'c', 'd', 'e']
lsC = ['あ', 'い', 'う']

for a, b, c in zip_longest(lsA, lsB, lsC, fillvalue='fill'):
	print(a, b, c)

#出力
# 1 a あ
# 2 b い
# 3 c う
# 4 d fill
# 5 e fill
fillvalue=で補填する値を指定できる
 値は1つのみで、リストごとに別の値を指定することはできない

2021年2月14日日曜日

random - python

■インポート


import random

■ランダムな値を取得


・実数

#0以上1未満
random.random()

#n以上m以下
random.uniform(n, m)

・整数

#0以上n未満
random.randrange(n)

#n以上m未満
random.randrange(n, m)

#n以上m未満(i間隔)
random.randrange(n, m, i)

#n以上m以下
random.randint(n, m)

・リストからランダムに値を取得

random.choice(['a', 'b', 'c'])

・リストをシャッフル

lsA = ['a', 'b', 'c']

random.shuffle(lsA)
print(lsA)

#出力
# ['b', 'a', 'c']

2021年2月5日金曜日

結合 - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df1 = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
df2 = pd.DataFrame({'列名1':['xxx','yyy','zzz'],'列名2':['aaa','ccc','a'],'列名3':['b','あ',3]})

print(df1)
print(df2)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
#
#    列名1  列名2 列名3
# 0  xxx  aaa   b
# 1  yyy  ccc   あ
# 2  zzz    a   3

■結合


・横に結合

df = pd.merge(df1, df2, on='列名2')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    333  ccc     あ   yyy     あ
pd.merge()の第一引数(left)、第二引数(right)にデータフレームを指定
on=で値を比較する列を指定
 デフォルトではinner join(値が等しい行のみ残す)となる
 on=で指定した同名の列はまとめられ
 他の列名が重複していると列名に語尾が追加される

df = pd.merge(df1, df2, left_on='列名3', right_on='列名2')
print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   zzz     a     3
 違う列名同士を当てる場合はleft_onright_onでそれぞれ指定

df = pd.merge(df1, df2, on=['列名2','列名3'])
print(df)

#出力
#    列名1_x  列名2 列名3 列名1_y
# 0    333  ccc   あ   yyy
 複数の列を当てる場合はリストで指定

#left join
df = pd.merge(df1, df2, on='列名2', how='left')
print(df)

#right join
df = pd.merge(df1, df2, on='列名2', how='right')
print(df)

#outer join
df = pd.merge(df1, df2, on='列名2', how='outer')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    222  bbb     2   NaN   NaN
# 2    333  ccc     あ   yyy     あ
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  333.0  ccc     あ   yyy     あ
# 2    NaN    a   NaN   zzz     3
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  222.0  bbb     2   NaN   NaN
# 2  333.0  ccc     あ   yyy     あ
# 3    NaN    a   NaN   zzz     3
how=で結合方法を指定できる
 当たらない行の値はNaNになる

#cross join
df = pd.merge(df1, df2, how='cross')

print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   xxx   aaa     b
# 1    111   aaa     a   yyy   ccc     あ
# 2    111   aaa     a   zzz     a     3
# 3    222   bbb     2   xxx   aaa     b
# 4    222   bbb     2   yyy   ccc     あ
# 5    222   bbb     2   zzz     a     3
# 6    333   ccc     あ   xxx   aaa     b
# 7    333   ccc     あ   yyy   ccc     あ
# 8    333   ccc     あ   zzz     a     3
pandas ver1.2.0からcross joinが追加

・縦に結合

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2] )
print(df)

#出力
#    列名1  列名2 列名3  列名4
# 0  111  aaa   a  NaN
# 1  222  bbb   2  NaN
# 2  333  ccc   あ  NaN
# 0  xxx  aaa   b    d
# 1  yyy  ccc   あ    d
# 2  zzz    a   3    d
pd.concat()に結合するデータフレームをリストで指定
 同じ列名が結合される
 違う列名がある場合、値がNaNで補完される
 インデックスは元の値を引き継ぐ

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2], join='inner', ignore_index=True)
print(df)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
# 3  xxx  aaa   b
# 4  yyy  ccc   あ
# 5  zzz    a   3
join='inner'とすると列名が等しいものだけ残す
ignore_index='True'とするとインデックスがリセットされる

行操作 - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
print(df)

#出力
#    列名1 列名2 列名3
# 0    111   aaa     a
# 1    222   bbb     2
# 2    333   ccc     あ

■行操作


・1行だけ抜き出す

row = df.loc[1]
print(row)

print(row['列名2'])

#出力
# 列名1    222
# 列名2    bbb
# 列名3      2
# Name: 1, dtype: object
#
# bbb
.loc[]にインデックス名を指定
 シリーズの行版のようなもの
 さらに[ ]で列名を指定して値を抜き出せる

row = df.iloc[2]
print(row)

#出力
# 列名1    333
# 列名2    ccc
# 列名3      あ
# Name: 2, dtype: object
.iloc[]に行数(0始まり)を指定しても同様
 ※この例ではインデックスと行数が等しいのでわかりにくい

・行の値を変更する

df.loc[0] = [444,'ddd','い']
print(df)

#出力
#    列名1  列名2 列名3
# 0  444  ddd   い
# 1  222  bbb   2
# 2  333  ccc   あ
.loc[]にリストを代入
 ※リストのサイズは列数に合わせる

・インデックスを変更する

df.index = ['x','y','z']
print(df)

#出力
#    列名1  列名2 列名3
# x  111  aaa   a
# y  222  bbb   2
# z  333  ccc   あ
 df.indexにリストを代入
 ※リストのサイズは行数に合わせる

df.index= ['x','y','z']
print(df)

df = df.reset_index()
print(df)

#出力
#    列名1  列名2 列名3
# x  111  aaa   a
# y  222  bbb   2
# z  333  ccc   あ
#
#   index  列名1  列名2 列名3
# 0     x  111  aaa   a
# 1     y  222  bbb   2
# 2     z  333  ccc   あ
.reset_index()でインデックスを通し番号で振り直せる
 前のインデックスは列として追加される
.reset_index(drop=True)とすると前のインデックスは残らない

・フィルター

df = df[ df['列名1']>200 ]
print(df)

#出力
#    列名1  列名2 列名3
# 1  222  bbb   2
# 2  333  ccc   あ
[ ]にフィルター条件を記載
 列はシリーズで指定

df = df[ (df['列名1']>200)&(df['列名3']=='あ') ]
print(df)

#出力
#    列名1  列名2 列名3
# 2  333  ccc   あ
 複数条件は「&(and条件)」か「|(or条件)」を使用

■参考


・フィルターについて詳しく

 データフレームをフィルターするには
df[ ]値がTrueかFalseのリストを指定する
df = df[ [False, True, False] ]
print(df)

#出力
#    列名1  列名2 列名3
# 1  222  bbb   2
 リストは残したい行をTrueとし、行数と同じサイズにする

print(df['列名1']>200)

#出力
# 0    False
# 1     True
# 2     True
# Name: 列名1, dtype: bool
 実際に条件部分だけ見ると、TrueかFalseのリストとなっている

2021年2月3日水曜日

列操作 - pandas -python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
print(df)

#出力
#    列名1 列名2 列名3
# 0    111   aaa     a
# 1    222   bbb     2
# 2    333   ccc     あ

■列操作


・列を抜き出す

df = df[ ['列名2','列名3'] ]
print(df)

#出力
#    列名2 列名3
# 0  aaa   a
# 1  bbb   2
# 2  ccc   あ
[ ]に列名のリストを指定
 列は指定した順になるので並べ替えにも使える

df = df[ ['列名2'] ]
print(type(df))

df = df['列名2']
print(type(df))

#出力
# <class 'pandas.core.frame.DataFrame'>
# <class 'pandas.core.series.Series'>
 1列抜き出す場合もリストで指定する
 リストでないとシリーズとして抜き出される

・列を削除する

df = df.drop(['列名2'], axis=1)
print(df)

#出力
#    列名1 列名3
# 0  111   a
# 1  222   2
# 2  333   あ
.drop()の第一引数に削除したい列名のリスト
 第二引数にaxis=1を指定(デフォルト(axis=0)だと行の削除になる)
 ※1列だけ削除する場合はリストでなくても可

・列を追加する

df['列名4'] = ['b','3','い']
print(df)

#出力
#    列名1  列名2 列名3 列名4
# 0  111  aaa   a   b
# 1  222  bbb   2   3
# 2  333  ccc   あ   い
[ ]で追加したい列名を指定
 そこに値のリストを代入する
 ※リストのサイズは行数と合わせる

df['列名4'] = 'd'
print(df)

#出力
#    列名1  列名2 列名3 列名4
# 0  111  aaa   a   d
# 1  222  bbb   2   d
# 2  333  ccc   あ   d
 値だけ指定した場合は全行で同じ値となる

df['列名4'] = df['列名1'] * 3
print(df)

#出力
#    列名1  列名2 列名3  列名4
# 0  111  aaa   a  333
# 1  222  bbb   2  666
# 2  333  ccc   あ  999
 元の列を使い演算することも可能

・列の値を変更する

df['列名3'] = [444, 555, 666]
print(df)

#出力
#    列名1  列名2  列名3
# 0  111  aaa  444
# 1  222  bbb  555
# 2  333  ccc  666
[ ]で変更したい列名を指定
 そこに値のリストを代入する

df['列名3'] = df['列名1'] * 3
print(df)

#出力
#    列名1  列名2  列名3
# 0  111  aaa  333
# 1  222  bbb  666
# 2  333  ccc  999
 元の列を使い演算することも可能

・列名を変更する

df = df.rename(columns={'列名1':'col1','列名3':'col3'})
print(df)

#出力
#    col1  列名2 col3
# 0   111  aaa    a
# 1   222  bbb    2
# 2   333  ccc    あ
.rename()columns=辞書型で指定
 keyが元の列名、valueが変更後の列名
 ※columns=を付けないとインデックスの名前変更になる

df.columns = ['col1','col2','col3']
print(df)

#出力
#    col1 col2 col3
# 0   111  aaa    a
# 1   222  bbb    2
# 2   333  ccc    あ
 全ての列名を変える場合はdf.columnsにリストを代入でも可
 ※リストのサイズは列数に合わせる