3.3. pandas 2#

3.3.1. 条件をつけて行や列を抽出する方法#

locは行の名前(ラベル)や列の名前、条件を指定して抽出するために用いることができます。

ilocは行や列の番号を指定して抽出することができます。

Note

loc iloc の違い

参考ページ

  • ilocは基本的に場所を示す整数(0からテーブルの長さ-1まで)で指定することができます。またTrue/Falseでの条件指定もできます。

  • locは基本的には場所の名前(label)やで指定することができます。またTrue/Falseでの条件指定もできます。

import pandas as pd
import numpy as np
df = pd.DataFrame({'price':[100, 40, 300, np.nan , 500, 1000, 300, 400, 240, 3000], 
                   'num': [5, 2, 1, 0, 4, 200, 7, 19, 20, 100],
                   'datetime': pd.date_range('20180601', periods=10, freq= '627H') })

priceが100より大きい行のみ抽出します。

df.loc[df['price']>100]
price num datetime
2 300.0 1 2018-07-23 06:00:00
4 500.0 4 2018-09-13 12:00:00
5 1000.0 200 2018-10-09 15:00:00
6 300.0 7 2018-11-04 18:00:00
7 400.0 19 2018-11-30 21:00:00
8 240.0 20 2018-12-27 00:00:00
9 3000.0 100 2019-01-22 03:00:00

priceが300以上の’price’列のみ抽出します。

df.loc[df['price']>=300, 'price']
2     300.0
4     500.0
5    1000.0
6     300.0
7     400.0
9    3000.0
Name: price, dtype: float64

複数の条件を指定することもできます。&AND条件を指定できます

df.loc[(df['price']>100)&(df['datetime']>'2018-11-01')]
price num datetime
6 300.0 7 2018-11-04 18:00:00
7 400.0 19 2018-11-30 21:00:00
8 240.0 20 2018-12-27 00:00:00
9 3000.0 100 2019-01-22 03:00:00

複数の条件をOrで指定することもできます。Orは|で示します。

df.loc[(df['price']>100) | (df['datetime']>'2018-11-01')]
price num datetime
2 300.0 1 2018-07-23 06:00:00
4 500.0 4 2018-09-13 12:00:00
5 1000.0 200 2018-10-09 15:00:00
6 300.0 7 2018-11-04 18:00:00
7 400.0 19 2018-11-30 21:00:00
8 240.0 20 2018-12-27 00:00:00
9 3000.0 100 2019-01-22 03:00:00

次に行や列の番号で抽出する場合です。この場合は、ilocが使えます。

df.iloc[:5, 1]
0    5
1    2
2    1
3    0
4    4
Name: num, dtype: int64
df.iloc[2,:] #2行目のデータを指定
price                     300.0
num                           1
datetime    2018-07-23 06:00:00
Name: 2, dtype: object
df.loc[2,:] #indexの名前(ラベル)が2のものを抽出
price                     300.0
num                           1
datetime    2018-07-23 06:00:00
Name: 2, dtype: object

3.3.1.1. 一意な値の集合#

列の中にあるユニークな値(重複がない値)を確認したい場合はunique()で確認できます。 次のDataFramefruitに何種類のフルーツに関するデータがあるか確認します。

fruit = pd.DataFrame({'category': ['banana','orange','apple','apple','orange','orange','apple','apple','apple','banana'],
                      "num_sell" : [100, 40, 30, 30, 40, 100, np.nan, 40, 1, 6],
                      "price" : [100, 130, 80, 150, 70, 75, np.nan, 90, 190, 110],})
fruit
category num_sell price
0 banana 100.0 100.0
1 orange 40.0 130.0
2 apple 30.0 80.0
3 apple 30.0 150.0
4 orange 40.0 70.0
5 orange 100.0 75.0
6 apple NaN NaN
7 apple 40.0 90.0
8 apple 1.0 190.0
9 banana 6.0 110.0
print(fruit['category'].unique())
print(len(fruit['category'].unique()))
['banana' 'orange' 'apple']
3

一意な値がそれぞれ何個出現しているかを確認するためには、value_counts()が便利です。

fruit['category'].value_counts()
category
apple     5
orange    3
banana    2
Name: count, dtype: int64
type(fruit['category'].value_counts()) #value_counts()はSeriesを返しています
pandas.core.series.Series

3.3.1.2. 欠損値の確認#

欠損値の扱いや要約統計量に関する扱いなどは後で改めて詳しく紹介する予定です。

fruit.isnull().sum()
category    0
num_sell    1
price       1
dtype: int64

3.3.1.3. 要約統計量#

要約統計量はdescribeを用いることで一括で確認できます。

fruit.describe()
num_sell price
count 9.000000 9.000000
mean 43.000000 110.555556
std 35.348267 39.721251
min 1.000000 70.000000
25% 30.000000 80.000000
50% 40.000000 100.000000
75% 40.000000 130.000000
max 100.000000 190.000000

3.3.1.4. Dataframeを値に応じてソートする#

sort_valuesを用いて行をソートします。byでどの列の値でソートするかを指定します。

defaultではascending(昇順)でソートします。

fruit.sort_values(by = ['num_sell']) 
category num_sell price
8 apple 1.0 190.0
9 banana 6.0 110.0
2 apple 30.0 80.0
3 apple 30.0 150.0
1 orange 40.0 130.0
4 orange 40.0 70.0
7 apple 40.0 90.0
0 banana 100.0 100.0
5 orange 100.0 75.0
6 apple NaN NaN

降順(descending)で表示する場合は、ascending=Falseにします。

fruit.sort_values(by = ['num_sell'], ascending = False) 
category num_sell price
0 banana 100.0 100.0
5 orange 100.0 75.0
1 orange 40.0 130.0
4 orange 40.0 70.0
7 apple 40.0 90.0
2 apple 30.0 80.0
3 apple 30.0 150.0
9 banana 6.0 110.0
8 apple 1.0 190.0
6 apple NaN NaN

複数の列でソートも可能です。

fruit.sort_values(by = ['category','price',], ascending = False) 
category num_sell price
1 orange 40.0 130.0
5 orange 100.0 75.0
4 orange 40.0 70.0
9 banana 6.0 110.0
0 banana 100.0 100.0
8 apple 1.0 190.0
3 apple 30.0 150.0
7 apple 40.0 90.0
2 apple 30.0 80.0
6 apple NaN NaN

3.3.1.5. 要素の削除#

dropは列や行を指定して削除するメソッドです。

dropだけでは元のDataFrameは変わりません。 df = df.drop(0) のように元のDataFrameに再代入するか、dropの引数にinplace =True(defaultはFalse)を与えると元のDataFrameの指定した行が削除されます。

その他の動作など詳しくはpandasのドキュメントを参照してください。

行の削除をdropを用いて行ってみます。

fruit.drop(3)
category num_sell price
0 banana 100.0 100.0
1 orange 40.0 130.0
2 apple 30.0 80.0
4 orange 40.0 70.0
5 orange 100.0 75.0
6 apple NaN NaN
7 apple 40.0 90.0
8 apple 1.0 190.0
9 banana 6.0 110.0

なお、上の1行だけではfruitそれ自体は変りません。次のようにfruitに代入するとfruit自体の0行目が削除されます

fruit = fruit.drop(0)

列の削除は同様にdropを用いて削除する列名を指定し、axis1とします

fruit.drop(['num_sell'],axis=1)
category price
1 orange 130.0
2 apple 80.0
3 apple 150.0
4 orange 70.0
5 orange 75.0
6 apple NaN
7 apple 90.0
8 apple 190.0
9 banana 110.0

上の1行だけではfruitそれ自体は変りません。fruitに代入するとfruit自体の0行目が削除されます

fruit = fruit.drop(['num_sell'],axis=1)

3.3.1.6. グループごとの集計などを確認する方法#

  • groupbyを用いるとかん単位ぐるーぷごとの集計や計算などが行えます。

  • groupbyと一緒に使えるファンクションとして、sum(), mean(), size()などがあります。自分で任意の関数を作成することもできます。

  • 詳細はpandasのドキュメントを確認してください。

fruit.groupby(['category']).sum() #Category別の合計販売個数
price
category
apple 510.0
banana 110.0
orange 275.0
fruit.groupby(['category']).mean() #Category別の平均販売個数
price
category
apple 127.500000
banana 110.000000
orange 91.666667
# 複数の条件を指定することもできます。
df.loc[(df['price']>100) & (df['datetime']>'2018-11-01')]
price num datetime
6 300.0 7 2018-11-04 18:00:00
7 400.0 19 2018-11-30 21:00:00
8 240.0 20 2018-12-27 00:00:00
9 3000.0 100 2019-01-22 03:00:00
# 複数の条件をOrで指定することもできます。Orは`|`で示します。
df.loc[(df['price']>100) | (df['datetime']>'2018-11-01')]
price num datetime
2 300.0 1 2018-07-23 06:00:00
4 500.0 4 2018-09-13 12:00:00
5 1000.0 200 2018-10-09 15:00:00
6 300.0 7 2018-11-04 18:00:00
7 400.0 19 2018-11-30 21:00:00
8 240.0 20 2018-12-27 00:00:00
9 3000.0 100 2019-01-22 03:00:00