今日はやる。
いやもうやっている。
今日でPandasの終わり。
結構覚えることが多いので、進めながら勝手に覚えてくれたら
良いという感じで進める。
■AIを学ぶ為の本格Python講座
PY18_Pandas_欠損値の処理
PY19_Pandas_データセットの連結・計算
今日学んだこと
Pandasでの欠損値
>>> data=pd.DataFrame({
... "c1":[1,2,None,np.nan],
... "c2":[1.2,2.3,None,np.nan],
... "c3":['aaa','bbb',None,np.nan],
... })
>>>
>>> data
c1 c2 c3
0 1.0 1.2 aaa
1 2.0 2.3 bbb
2 NaN NaN None
3 NaN NaN NaN
>>>
Pandasでは各列ごとにデータ型が決まる。
c1、c2列は数値となり、Noneとしてもnp.nanとしても
どちらもNanとなるが、
c3については、数字じゃないので、Noneは
そのままNoneと表示される。
欠損値を探す
欠損値データの部分がTrueとなる。
>>> data.isna()
c1 c2 c3
0 False False False
1 False False False
2 True True True
3 True True True
>>>
別の書き方
>>> pd.isna(data)
c1 c2 c3
0 False False False
1 False False False
2 True True True
3 True True True
>>>
逆に、欠損値をfalseと表現するnotna()
>>> data.notna()
c1 c2 c3
0 True True True
1 True True True
2 False False False
3 False False False
>>>
別の書き方
>>> pd.notna(data)
c1 c2 c3
0 True True True
1 True True True
2 False False False
3 False False False
>>>
欠損値の削除
欠損値のある行を削除する。
>>> data.dropna()
c1 c2 c3
0 1.0 1.2 aaa
1 2.0 2.3 bbb
>>>
代入もできる
>>> aaa=data.dropna()
>>> aaa
c1 c2 c3
0 1.0 1.2 aaa
1 2.0 2.3 bbb
>>>
>>> aaa.loc[0,'c1']=555
>>>
>>> aaa
c1 c2 c3
0 555.0 1.2 aaa
1 2.0 2.3 bbb
>>>
dorpna()は元のDataFrameを壊さない。
aaaに代入して555としたけど、dataは変わっていない。
dropnaは、aaa=data.dropna() の際に、aaaに
中味をコピーしているので、aaaに値を代入しても
元のdataに影響を与えない。
>>> data
c1 c2 c3
0 1.0 1.2 aaa
1 2.0 2.3 bbb
2 NaN NaN None
3 NaN NaN NaN
>>>
>>> df=pd.DataFrame(
... [[1,np.nan,2],
... [2,3,5],
... [np.nan,4,6]]
... )
>>> df
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6
>>>
欠損値のある行を削除
>>> df.dropna()
0 1 2
1 2.0 3.0 5
>>>
欠損値のある列を削除もできる。
欠損値のなかった2列目だけ表示
>>> df.dropna(axis='columns')
2
0 2
1 5
2 6
>>>
1列全体に欠損値を代入。
>>> df[3]=np.nan
>>> df
0 1 2 3
0 1.0 NaN 2 NaN
1 2.0 3.0 5 NaN
2 NaN 4.0 6 NaN
>>>
>>>
1列全部欠損値の列だけを削除。
howで、1つでも値がないか、全部ないかを制御できる。
how='all'指定で、全部値がない行だけを削除
列3だけがなくっている。
>>> df.dropna(axis='columns',how='all')
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6
>>>
1行に値が3個あれば残す。値の数のしきい値で指定する。
値が2個しかない0行目と2行目が削除された。
>>> df.dropna(axis='rows',thresh=3)
0 1 2 3
1 2.0 3.0 5 NaN
>>>
欠損値を値で埋める。
>>> data=pd.Series([1,np.nan,2,None,3],index=list('abcde'))
>>> data
a 1.0
b NaN
c 2.0
d NaN
e 3.0
dtype: float64
>>>
欠損値を0で埋める
>>> data.fillna(0)
a 1.0
b 0.0
c 2.0
d 0.0
e 3.0
dtype: float64
>>>
1つ前の行の値を使って値を入れる
ffill(エフフィル)を使うと前の行の値を入れる。
>>> data.fillna(method='ffill')
a 1.0
b 1.0
c 2.0
d 2.0
e 3.0
dtype: float64
bfill(ビーフィル)を使うと後の行の値を入れる。
>>> data.fillna(method='bfill')
a 1.0
b 2.0
c 2.0
d 3.0
e 3.0
dtype: float64
>>>
DataFrameの欠損値
>>> df=pd.DataFrame(
... [[1,np.nan,2],
... [2,3,5],
... [np.nan,4,6]]
... )
>>>
>>> df
0 1 2
0 1.0 NaN 2
1 2.0 3.0 5
2 NaN 4.0 6
>>>
DataFrameのffill
行ごとに前の値をコピーする。
0行目は、その行で、1つ前の値(0列の値(1))が1列目に入れられるが
2行目は、その行で前の値がないので、そのままになる。
>>> df.fillna(method='ffill',axis=1)
0 1 2
0 1.0 1.0 2.0
1 2.0 3.0 5.0
2 NaN 4.0 6.0
>>>
bfillで後ろの値のコピーができる。
>>> df.fillna(method='bfill',axis=1)
0 1 2
0 1.0 2.0 2.0
1 2.0 3.0 5.0
2 4.0 4.0 6.0
>>>
―――――――――――――――――――――――――――――――――――
Pandas_データセットの連結
データセットの連結
Seriesを連結できる。
>>> test1=pd.Series(['A','B','C'],index=[1,2,3])
>>> test1
1 A
2 B
3 C
dtype: object
>>>
>>> test2=pd.Series(['D','E','F'],index=[4,5,6])
>>> test2
4 D
5 E
6 F
dtype: object
>>>
>>> pd.concat([test1,test2])
1 A
2 B
3 C
4 D
5 E
6 F
dtype: object
>>>
>>> pd.concat([test2,test1])
4 D
5 E
6 F
1 A
2 B
3 C
dtype: object
>>>
関数を作って連結させる。
>>> def make_df(cols,ind):
... return pd.DataFrame({c: [str(c)+str(i) for i in ind] for c in cols},ind)
...
>>> df1=make_df('AB',[1,2])
>>> df1
A B
1 A1 B1
2 A2 B2
>>>
>>> df2=make_df('AB',[3,4])
>>>
>>> pd.concat([df1,df2])
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4
>>>
>>>
concatとは別の関数(append)でも連結できる。
>>> df1.append(df2)
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4
>>>
>>>
>>> df3=make_df('AB',[0,1])
>>> df3
A B
0 A0 B0
1 A1 B1
>>>
>>> df4=make_df('CD',[0,1])
>>> df4
C D
0 C0 D0
1 C1 D1
>>>
axis=0のときは、縦方向(行方向)に連結したけど、
axis=1のときは、横方向(列方向)に連結される。
>>> pd.concat([df3,df4],axis=1)
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
>>>
連結したときに値がないところは、NaNが入る。
>>> df5=make_df('ABC',[1,2])
>>> df5
A B C
1 A1 B1 C1
2 A2 B2 C2
>>>
>>> df6=make_df('BCD',[3,4])
>>> df6
B C D
3 B3 C3 D3
4 B4 C4 D4
>>>
>>>
値のないところはNaNとなった。
>>> pd.concat([df5,df6])
A B C D
1 A1 B1 C1 NaN
2 A2 B2 C2 NaN
3 NaN B3 C3 D3
4 NaN B4 C4 D4
>>>
innerを使うと、両方にあるものだけを連結させる。
先ほどは、A、D列にNaNが表示されたが、innerの場合は、
NaNのあるA,D列は表示されず、全行に値のあるB、C列が表示される。
>>> pd.concat([df5,df6],join='inner')
B C
1 B1 C1
2 B2 C2
3 B3 C3
4 B4 C4
>>>
merge
DataFrame同士を合体する。
>>> test1 = pd.DataFrame({
... 'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],
... 'group': ['Accounting', 'Engineering', 'Engineering', 'HR']
... })
>>> test1
employee group
0 Bob Accounting
1 Jake Engineering
2 Lisa Engineering
3 Sue HR
>>>
>>> test2 = pd.DataFrame({
... 'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],
... 'hire_date': [2004, 2008, 2012, 2014]
... })
>>>
>>> test2
employee hire_date
0 Lisa 2004
1 Bob 2008
2 Jake 2012
3 Sue 2014
>>>
mergeコマンドで、DataFrame同士を合体できる。
同じ列の値ごとにうまくマージしてくれる。
>>> test3 = pd.merge(test1, test2)
>>> test3
employee group hire_date
0 Bob Accounting 2008
1 Jake Engineering 2012
2 Lisa Engineering 2004
3 Sue HR 2014
>>>
>>> test4 = pd.DataFrame({
... 'group': ['Accounting', 'Engineering', 'HR'],
... 'supervisor': ['Carly', 'Guido', 'Steve']
... })
>>> test4
group supervisor
0 Accounting Carly
1 Engineering Guido
2 HR Steve
>>>
うまくマージしてくれる。
>>> pd.merge(test3,test4)
employee group hire_date supervisor
0 Bob Accounting 2008 Carly
1 Jake Engineering 2012 Guido
2 Lisa Engineering 2004 Guido
3 Sue HR 2014 Steve
>>>
>>> test5 = pd.DataFrame({
... 'group': ['Accounting', 'Accounting', 'Engineering', 'Engineering', 'HR', 'HR'],
... 'skills': ['math', 'spreadsheets', 'coding', 'linux', 'spreadsheets', 'organization']
... })
>>> test5
group skills
0 Accounting math
1 Accounting spreadsheets
2 Engineering coding
3 Engineering linux
4 HR spreadsheets
5 HR organization
>>>
特定のキー(今回はgroup)に対してマージできる。
>>> pd.merge(test1,test5)
employee group skills
0 Bob Accounting math
1 Bob Accounting spreadsheets
2 Jake Engineering coding
3 Jake Engineering linux
4 Lisa Engineering coding
5 Lisa Engineering linux
6 Sue HR spreadsheets
7 Sue HR organization
>>>
キーを指定してマージできる。
>>> pd.merge(test1,test2, on='employee')
employee group hire_date
0 Bob Accounting 2008
1 Jake Engineering 2012
2 Lisa Engineering 2004
3 Sue HR 2014
>>>
>>> test6 = pd.DataFrame({
... 'name': ['Peter', 'Paul', 'Mary'],
... 'food': ['fish', 'beans', 'bread']},
... columns=['name', 'food']
... )
>>> test6
name food
0 Peter fish
1 Paul beans
2 Mary bread
>>>
>>> test7 = pd.DataFrame({
... 'name': ['Mary', 'Joseph'],
... 'drink': ['wine', 'beer']},
... columns=['name', 'drink']
... )
>>> test7
name drink
0 Mary wine
1 Joseph beer
>>>
ない行のデータ同士をマージすると
デフォルトでは、あるところだけをマージする。
(デフォルトのinner)
>>> pd.merge(test6,test7)
name food drink
0 Mary bread wine
>>>
outerを指定すると、ないところは欠損値が入れらえる。
>>> pd.merge(test6,test7,how='outer')
name food drink
0 Peter fish NaN
1 Paul beans NaN
2 Mary bread wine
3 Joseph NaN beer
>>>
leftを指定すると、変数の左のデータ(今回はtest6)を元にマージされる。
test6のデータは全て表示される。
>>> pd.merge(test6,test7,how='left')
name food drink
0 Peter fish NaN
1 Paul beans NaN
2 Mary bread wine
>>>
集約、最大、最小、平均
Seriesの場合
〇合計
>>> ser=pd.Series(np.random.rand(5))
>>> ser
0 0.632377
1 0.534740
2 0.070234
3 0.807978
4 0.602560
dtype: float64
>>>
>>>
>>> ser.sum()
2.6478893393919103
>>>
〇平均
>>> ser.mean()
0.529577867878382
>>>
DataFrameの場合
>>> df=pd.DataFrame({
... 'A':np.random.rand(5),
... 'B':np.random.rand(5)
... })
>>>
>>> df
A B
0 0.947485 0.471890
1 0.576076 0.066746
2 0.106285 0.540292
3 0.221824 0.290662
4 0.769744 0.470651
>>>
〇合計
データフレームの場合は、行方向に合計される。
>>> df.sum()
A 2.621414
B 1.840241
dtype: float64
>>>
〇平均
データフレームの場合は、行方向に計算される。
>>> df.mean()
A 0.524283
B 0.368048
dtype: float64
>>>
オプションを指定することにより、
列方向に計算させることもできる。
>>> df.mean(axis='columns')
0 0.709687
1 0.321411
2 0.323289
3 0.256243
4 0.620197
dtype: float64
>>>
describeを使うと、よく使う計算を纏めておこなってくれる。
>>> import pandas as pd
>>> from sklearn import datasets
>>>
>>> iris=datasets.load_iris()
>>> df=pd.DataFrame(iris.data,columns=iris.feature_names)
>>> df.describe()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333
std 0.828066 0.435866 1.765298 0.762238
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000
>>>
グループ化
>>> df=pd.DataFrame({
... 'key':['A','B','C','A','B','C'],
... 'data':range(6)
... },columns=['key','data'])
>>>
>>> df
key data
0 A 0
1 B 1
2 C 2
3 A 3
4 B 4
5 C 5
>>>
keyの列で同じものを纏めてくれる。
(Aは0と3なので足して3)
>>> df.groupby('key').sum()
data
key
A 3
B 5
C 7
>>>
>>>
>>>
>>> df = pd.DataFrame({
... 'key': ['A', 'B', 'C', 'A', 'B', 'C'],
... 'data1': range(6),
... 'data2': np.random.randint(0, 10, 6)
... }, columns = ['key', 'data1', 'data2'])
>>>
>>> df
key data1 data2
0 A 0 2
1 B 1 4
2 C 2 5
3 A 3 8
4 B 4 2
5 C 5 9
>>>
計算方法を指定して、まとめて実行してくれる。
(medianは中央値)
>>> df.groupby('key').aggregate(['min', np.median, max])
data1 data2
min median max min median max
key
A 0 1.5 3 2 5 8
B 1 2.5 4 2 3 4
C 2 3.5 5 5 7 9
>>>
勉強時間
今日: 1.0時間
総勉強時間: 34時間
お得キャンペーンの紹介
ラビットチャレンジの
Amazonギフト券「5,000円」プレゼントキャンペーンのお知らせ
申込時に、以下コードを使えば、入会金が5000円引かれるようです。
また、紹介した僕にも5000円のAmazonギフト券が送られるようです。
お得なので、よかったら申込時お使いください。
紹介コード:friend0019697
※本キャンペーンの期間は、 2021年9月15日~10月31日 です。
「お友達紹介キャンペーン」特設ページ:
https://ai99