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
を用いて削除する列名を指定し、axis
を1
とします
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 |