Pythonのデータサイエンスの基礎について、Udemyの以下リンクの学習教材で学んだ内容の内、Pandasについてまとめています。
Series
SeriesはNumpyのArrayのようなもの。
Numpy のArrayとPandasの違いは、Seriesにはindexが付く
import pandas as pd
from pandas import Series
obj = Series([3,6,9,12])
obj
>
0 3
1 6
2 9
3 12
値やインデックスを取り出す
obj.values
> array([ 3, 6, 9, 12])
obj.index
> RangeIndex(start=0, stop=4, step=1)
indexに文字列を当てる
以下は第二次世界大戦での各国の国ごとの死者数のデータを作成する例
ww2_cas = Series([87000000, 43000000, 30000000, 2100000, 400000], index=['USSR', 'Germany', 'China', 'Japan', 'USA'])
ww2_cas
>
USSR 87000000
Germany 43000000
China 3000000
Japan 2100000
USA 400000
条件式を使う
ww2_cas[ww2_cas>4000000]
>
USSR 87000000
Germany 43000000
これはどんな結果が返ってきているかというとTrue, Falseの結果が返ってきている。
ww2_cas>4000000
>
USSR True
Germany True
China False
Japan False
USA False
dtype: bool
to_dict
Pythonの辞書型を作ることができる。
ww2_dict = ww2_cas.to_dict()
ww2_dict
>
{'USSR': 87000000,
'Germany': 43000000,
'China': 3000000,
'Japan': 2100000,
'USA': 400000}
辞書を基にSeriesを作ることもできる
ww2_Series = Series(ww2_dict)
ww2_Series
>
USSR 87000000
Germany 43000000
China 3000000
Japan 2100000
USA 400000
辞書を基にSeriesを作成する
countriesというindexを作成し、作成済みのSeriesであるww2_dictを基に新しいobj2というSeriesを作成する。
countries = ['China', 'Germany', 'Japan', 'USA', 'USSR', 'Argentina']
obj2 = Series(ww2_dict, index = countries)
obj2
>
China 3000000.0
Germany 43000000.0
Japan 2100000.0
USA 400000.0
USSR 87000000.0
Argentina NaN
ww2_dictには無かったArgentinaはNaNとなる。
Series同士の足し算
indexが揃っていれば足し算してくれる。
ww2_Series + obj2
>
Argentina NaN
China 6000000.0
Germany 86000000.0
Japan 4200000.0
USA 800000.0
USSR 174000000.0
Seriesに名前を付ける
obj2.name = "第二次世界大戦の死者数"
obj2
>
China 3000000.0
Germany 43000000.0
Japan 2100000.0
USA 400000.0
USSR 87000000.0
Argentina NaN
Name: 第二次世界大戦の死者数
indexにも名前を付けることができる。
obj2.index.name = 'Countries'
obj2
>
Countries
China 3000000.0
Germany 43000000.0
Japan 2100000.0
USA 400000.0
USSR 87000000.0
Argentina NaN
Name: 第二次世界大戦の死者数
DataFrame
pandasのSeriesとDataFrameを使えるようにする。
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
コピーしたデータの貼り付け
webブラウザ上でコピーした上で、以下を実行
mp_frame=pd.read_clipboard()
mp_frame
出力結果
カラムを取得
mp_frame.columns
>
Index(['順位', 'コード', '市場', '名称', '取引値', '発行済み株式数', '時価総額(百万円)', '単元株数', '掲示板'], dtype='object')
ちなみにコピー元サイトはこちら
列の名前を取得
以下のようにカラム名で指定する
mp_frame['時価総額(百万円)']
>
1 34,905,916
2 17,862,898
3 17,669,038
4 13,303,110
5 12,872,604
6 12,102,027
7 9,212,559
Name: 時価総額(百万円)
複数列の取り出しの場合
mp_frame[['市場', '時価総額(百万円)']]
出力結果
(データコピー元のセルの関係でカラムがずれています。)
新しいDataFrameを作成する
上記は取得をしているのに対し、今回は新しくDataFrame を作成する。
出力結果としては同じ。
DataFrame(mp_frame, columns=['市場', '時価総額(百万円)'])
最初の数行を取り出す
5行を取り出す場合
mp_frame.head()
行数を指定する場合
引数を指定することができる。
mp_frame.head(3)
こうすると3行が取得できる。
最後からいくつかの数行を取り出す
headと同様に…
mp_frame.tail()
mp_frame.tail(3)
index を使ってデータにアクセスする
ixを使う。
mp_frame.ix[3]
新しい列を追加する
mp_frame['配当'] = "10円"
これで配当というカラムに全て10円が追加される。
列を削除する
頭にdelを付ける。
del mp_frame['コード']
これで、コードカラムの列が削除される。
DataFrameを辞書から作る
まずは、Pythonの辞書型をdataという名前で作成
city_frameという名前でDataFrameを作成
data = {'City':['SF', 'LA', 'NYC'], 'Population':[837000, 3880000, 8400000]}
data
>
{'City': ['SF', 'LA', 'NYC'], 'Population': [837000, 3880000, 8400000]}
city_frame = DataFrame(data)
city_frame
出力結果
indexの基本
簡単なSeriesを作成
おさらいになるが、Seriesは以下のように値とindexを指定して作成することができる。
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
my_ser = Series([1,2,3,4], index=['A','B', 'C', 'D'])
my_ser
>
A 1
B 2
C 3
D 4
indexを取り出す
.indexで取り出せる。
my_index = my_ser.index
my_index
>
Index(['A', 'B', 'C', 'D'], dtype='object')
indexの中から要素を取り出す
my_index[0]
>
'A'
indexを変える
新たにrandnというものを使う。
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
from numpy.random import randn
randnは正規分布に従った乱数を返すもの。
indexを書き換える
reindexを使い、indexを追加すると、indexが追加され、valueにはNaNが入る。
ser1 = Series([1,2,3,4], index = ['A', 'B', 'C', 'D'])
ser1
>
A 1
B 2
C 3
D 4
ser2 = ser1.reindex(['A', 'B', 'C', 'D', 'E', 'F'])
ser2
>
A 1.0
B 2.0
C 3.0
D 4.0
E NaN
F NaN
valueを指定する場合
ser2.reindex(['A', 'B', 'C', 'D', 'E', 'F', 'G'], fill_value=0)
>
A 1.0
B 2.0
C 3.0
D 4.0
E NaN
F NaN
G 0.0
行や列を削除する
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
ser1 = Series(np.arange(3), index=['a', 'b', 'c'])
ser1
>
a 0
b 1
c 2
indexを指定して削除する
dropを使う。
ser1.drop('b')
>
a 0
c 2
これでbのindexを削除できる。
行の削除
dframe1 = DataFrame(np.arange(9).reshape((3,3)), index=['SF', 'LA', 'NY'], columns=['pop', 'size', 'year'])
dframe1
出力結果
これは基のDataFrameを削除したわけではなく、削除したDateFrameを表示しているに過ぎない。
列の削除
カラム名と、軸を指定する。
dframe1.drop('year', axis=1)
データを取り出す
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
ser1 = Series(np.arange(3), index=['a', 'b', 'c'])
ser1 = 2* ser1
ser1
>
a 0
b 2
c 4
データにアクセスする
indexでもindex番号でもアクセスできる。
ser1['b']
>
2
ser1[1]
>
2
範囲の指定
ser1[0:3]
>
a 0
b 2
c 4
0から3の手間
文字列を使ったindex
同時に複数を指定できる。
ser1[['a','b']]
>
a 0
b 2
条件式を使う
3以上のみを出力
ser1[ser1>3]
3以上を10に置き換え
ser1[ser1>3] = 10
ser1
>
a 0
b 2
c 10
DaraFrameの場合
まずはDataFrameを作成
dframe = DataFrame(np.arange(25).reshape((5,5)), index=['NY','LA', 'SF', 'DC', 'Chi'], columns=['A', 'B', 'C', 'D', 'E'])
カラムを指定、条件付きで取得
行を取得
dframe.loc['LA']
>
A 5
B 6
C 7
D 8
E 9
dframe.iloc[1]
>
A 5
B 6
C 7
D 8
E 9
同じ結果が取得できる。
形の違うデータの計算
Series
形の違う2つのSeriesを用意し足し算する。
ser1 = Series([0,1,2], index=['A', 'B', 'C'])
ser1
>
A 0
B 1
C 2
ser2 = Series([3,4,5,6], index=['A', 'B', 'C', 'D'])
ser2
>
A 3
B 4
C 5
D 6
ser1 + ser2
>
A 3.0
B 5.0
C 7.0
D NaN
結論:片方に無いindexはNaNとなる。
NaNとは
Not a Numberの略
DataFrame
2×2と3×3のDataFrameを作る。
dframe1 = DataFrame(np.arange(4).reshape((2,2)), columns=list('AB'), index=['NYC','LA'])
dframe2 = DataFrame(np.arange(9).reshape((3,3)), columns=list('ADC'), index=['NYC','SF', 'LA'])
dframe1 + dframe2
カラム名はこのようにlistで指定することができる。
出力結果
これらを足し合わせると、カラムが合っていないところはNaNとなる。
NaNになってしまうのを避ける方法
.addとすることで、存在する値の部分を埋めることができる。
dframe1.add(dframe2, fill_value=0)
DataFrameからSeriesを引く計算をする
DataFrameからSeriesを取り出し、
dframe2
dframe2 - ser3
行ごとに0, 1, 2が引かれる。
データの並び替えと順番
簡単なSeriesを作成
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
ser1 = Series(range(3), index=['C', 'A', 'B'])
ser1
>
C 0
A 1
B 2
indexを使ってソート
ser1.sort_index()
>
A 1
B 2
C 0
値でのソート
orderを使う。
orderはバージョン変更により使えなくなった。
現在は、sort_values()
ser1.sort_values()
>
C 0
A 1
B 2
もう少しわかりやすいように、まずは乱数でSeriesを作成。
from numpy.random import randn
ser2 = Series(randn(10))
ser2
>
0 -1.090949
1 -0.576363
2 0.282948
3 0.804355
4 -0.284147
5 0.713147
6 -0.318596
7 -0.731993
8 -0.826768
9 1.504588
rank
並び替えたときに何番目になるか
ser2.rank()
>
0 1.0
1 4.0
2 7.0
3 9.0
4 6.0
5 8.0
6 5.0
7 3.0
8 2.0
9 10.0
データの統計量
まずはArrayを作成
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
arr = np.array([[1,2,np.nan], [np.nan, 3,4]])
arr
>
array([[ 1., 2., nan],
[nan, 3., 4.]])
ここで作ったArrayを基にDataFrameを作る。
dframe1 = DataFrame(arr, index=['A', 'B'], columns=['One', 'Two', 'Three'])
これにより名前を付与することができる。
列ごとの合計値を計算
dframe1.sum()
>
One 1.0
Two 5.0
Three 4.0
実はこの()は0の省略
行ごとの合計値を計算
dframe1.sum(axis=1)
>
A 3.0
B 7.0
列ごとの最小値/最大値
dframe1.min()
>
One 1.0
Two 2.0
Three 4.0
カラムの最小値がどの行か
idxminを使う。
dframe1.idxmin()
>
One A
Two A
Three B
maxはminを変えるだけ!
累積計算
dframe1.cumsum()
TwoのBは2+3で5になっている。
まとまった情報を求める
dframe1.describe()
pandas.ioはバージョン変更により使用ができなくなり、
pandas_datareaderとなっている。
以下を実施したがエラー
import pandas_datareader
そのため、以下を実施
pip install pandas_datareader
株価を取得するためにまずは2つimport
import pandas_datareader as pdweb
import datetime
3つのティッカーシンボルと、期間を指定して株価を取得
prices = pdweb.get_data_yahoo(['AAPL', 'GM', 'MSFT'],
start=datetime.datetime(2020,11,1),
end=datetime.datetime(2021,11,1))['Adj Close']
prices.head()
headにより先頭の5つを取得
変化の割合を計算
rets = prices.pct_change()
rets
描画をwebブラウザに埋め込む命令をする。
%matplotlib inline
すると、以下でブラフを出力することができる。
prices.plot()
相関係数を求める
corrを使う。
相関係数はグラフ化して求める事もできる。
重複データの取り除き、集計
値が重複しているSeriesを作る。
ser1 = Series(['w', 'w', 'x', 'y', 'w', 'x'])
ser1
>
0 w
1 w
2 x
3 y
4 w
5 x
unique
重複をまとめてくれる。
ser1.unique()
>
array(['w', 'x', 'y'], dtype=object)
value_counts
重複数を集計する。
ser1.value_counts()
>
w 3
x 2
y 1
欠損(Null)値の扱い
新たにnanというものを追加して、必要なものものをimportする。
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
from numpy import nan
NaNを含んだSeriesを作成
data = Series(['one', 'two', nan, 'four'])
data
>
0 one
1 two
2 NaN
3 four
Nullかどうかの判断
data.isnull()
>
0 False
1 False
2 True
3 False
欠損値を取り除く
dropnaを使用
data.dropna()
>
0 one
1 two
3 four
NaNを含んだDataFrameを作成
dframe = DataFrame([[1,2,3], [nan,5,6], [7,nan,9],[nan,nan,nan]])
dframe
欠損値を取り除く
Null値がある行がすべて消える。
dframe.dropna()
全てが欠損値となっている行だけ消す
dframe.dropna(how='all')
列を削除する場合
dframe.dropna(axis=1)
axis1は列を意味しており、これでNullの列を削除できる。
欠損値で無い値の数をしきい値にする
threshを使う。
thresh=3とすると、欠損値で無い値が3個以上無い行は削除される。
欠損値を別のデータで埋める
fillnaを使う。
dframe2.fillna(1)
これで、欠損値NaNを1で埋めることができる。
埋める値を列ごとに指定する
dframe2.fillna({0:0, 1:1, 2:2, 3:3})
0列は0、1列は1となる。
indexの階層構造
randomパッケージから、randn関数もimport
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
from numpy import nan
階層構造の確認
ser = Series(np.random.randn(6), index=[[1,1,1,2,2,2], ['a','b','c','a','b','c']])
ser
>
1 a 0.401007
b -1.178415
c -1.688628
2 a -1.243104
b -0.238969
c 0.821362
このように1や2を複数作ると、階層構造となる。
indexだけを表示してみると、、
ser.index
>
MultiIndex([(1, 'a'),
(1, 'b'),
(1, 'c'),
(2, 'a'),
(2, 'b'),
(2, 'c')],
)
Seriesを基にDataFrameを作る
dframe = ser.unstack()
dframe
逆にDataFrameからSeriesを呼ぶこともできる
dframe.unstack()
これだと列と行がひっくり返ってしまっているので、
dframe.T.unstack()
新たにDataFrameを作成
行のindexに名前を付ける
カラムに名前を付ける
カラムの階層を入れ替える
swaplevelを使い、横方向のaxis1を指定する。
行のソートをする
dframe2.sort_index(1)
引数の1はINDEX2の列をソートという意味
階層の計算
Tempの階層の合計値を求める。
コメント