pandasで欠損値がある値を補完してみる

2020年12月21日

pandasで欠損値がある値を補完してみる

実践データ分析100本ノックをやっています。只今データ補完の章をやっております。
理解を深める為にコードをばらしおります。


#データ用意
fruits = [
    {'item': 'apple', 'price': 200,  'stock': 20, 'country': 'japan', 'date':202001},
    {'item': 'banana','price': 300,  'stock': 30, 'country': 'japan', 'date':202001},
    {'item': 'orange','price': 150,  'stock': 40, 'country': 'japan', 'date':202001},
    {'item': 'apple', 'price': 200,  'stock': 20, 'country': 'japan', 'date':202002},
    {'item': 'banana','price': None, 'stock': 40, 'country': 'japan', 'date':202002},
    {'item': 'orange','price': 150,  'stock': 30, 'country': 'japan', 'date':202002},
    {'item': 'apple', 'price': 200,  'stock': 20, 'country': 'japan', 'date':202003},
    {'item': 'banana','price': None, 'stock': 50, 'country': 'japan', 'date':202003},
    {'item': 'orange','price': None, 'stock': 10, 'country': 'japan', 'date':202003},
]


#データフレーム化
df = pd.DataFrame(fruits)
# print(df)
#      item  price  stock country    date
# 0   apple  200.0     20   japan  202001
# 1  banana  300.0     30   japan  202001
# 2  orange  150.0     40   japan  202001
# 3   apple  200.0     20   japan  202002
# 4  banana    NaN     40   japan  202002
# 5  orange  150.0     30   japan  202002
# 6   apple  200.0     20   japan  202003
# 7  banana    NaN     50   japan  202003
# 8  orange    NaN     10   japan  202003


#値段のカラムの欠損値を確認
flg_is_null = df["price"].isnull()
# print(flg_is_null)
# 0    False
# 1    False
# 2    False
# 3    False
# 4     True
# 5    False
# 6    False
# 7     True
# 8     True


#欠損値がある行を取得
df.loc[flg_is_null]
# print(df.loc[flg_is_null])
#      item  price  stock country    date
# 4  banana    NaN     40   japan  202002
# 7  banana    NaN     50   japan  202003
# 8  orange    NaN     10   japan  202003


#欠損値がある行をカラムを指定して取得
df.loc[flg_is_null, "item"]
# print(df.loc[flg_is_null, "item"])
# 4    banana
# 7    banana
# 8    orange


#欠損値がある行をカラムを指定して、重複を排除して取得
df.loc[flg_is_null, "item"].unique()
# print(df.loc[flg_is_null, "item"].unique())
# ['banana' 'orange']


#欠損値がないデータを取得
df.loc[(~flg_is_null)]
# print(df.loc[(~flg_is_null)])
#      item  price  stock country    date
# 0   apple  200.0     20   japan  202001
# 1  banana  300.0     30   japan  202001
# 2  orange  150.0     40   japan  202001
# 3   apple  200.0     20   japan  202002
# 5  orange  150.0     30   japan  202002
# 6   apple  200.0     20   japan  202003


#行をカラムの値を指定して取得
df.loc[df["item"] == "banana", "price"]
# print(df.loc[df["item"] == "banana", "price"])
# 1    300.0
# 4      NaN
# 7      NaN


#欠損値がない行をカラムの値を指定して取得
df.loc[(~flg_is_null) & (df["item"] == "banana")]
# print(df.loc[(~flg_is_null) & (df["item"] == "banana")])
#      item  price  stock country    date
# 1  banana  300.0     30   japan  202001
df.loc[(~flg_is_null) & (df["item"] == "orange")]
# print(df.loc[(~flg_is_null) & (df["item"] == "orange")])
#      item  price  stock country    date
# 2  orange  150.0     40   japan  202001
# 5  orange  150.0     30   japan  202002


#欠損値がある行をカラムの値を指定して修正
#UPDATE df SET price=0 WHERE price IS NULL AND item="banana"
df["price"].loc[(flg_is_null)&(df["item"]=="banana")] = 0
# print(df)
#      item  price  stock country    date
# 0   apple  200.0     20   japan  202001
# 1  banana  300.0     30   japan  202001
# 2  orange  150.0     40   japan  202001
# 3   apple  200.0     20   japan  202002
# 4  banana    0.0     40   japan  202002
# 5  orange  150.0     30   japan  202002
# 6   apple  200.0     20   japan  202003
# 7  banana    0.0     50   japan  202003
# 8  orange    NaN     10   japan  202003


#欠損値がある行をカラムの値を指定して修正
#UPDATE df SET price=0 WHERE price IS NULL AND item="banana" OR item="orange"
#ORの「|」を使用する時は「()」でくくる
df["price"].loc[(flg_is_null)&((df["item"]=="banana")|(df["item"]=="orange"))] = 0
# print(df)
#      item  price  stock country    date
# 0   apple  200.0     20   japan  202001
# 1  banana  300.0     30   japan  202001
# 2  orange    0.0     40   japan  202001
# 3   apple  200.0     20   japan  202002
# 4  banana    0.0     40   japan  202002
# 5  orange    0.0     30   japan  202002
# 6   apple  200.0     20   japan  202003
# 7  banana    0.0     50   japan  202003
# 8  orange    0.0     10   japan  202003


#----欠損のある値段を同商品の値段の最大値で補完----

#欠損値のある行のアイテム名を重複を排除して取得
for trg in list(df.loc[flg_is_null, "item"].unique()):
    #該当するアイテム名の欠損値がない値段の最大値を取得
    price = df.loc[(~flg_is_null)&(df["item"]==trg), "price"].max()
    print(trg+"の一番高い価格は"+str(price)+"です。")
    #該当するアイテム名の欠損値がある値段を上記で取得した最大値に変更
    df["price"].loc[(flg_is_null)&(df["item"]==trg)] = price

# print(df)
# bananaの一番高い価格は300.0です。
# orangeの一番高い価格は150.0です。
#      item  price  stock country    date
# 0   apple  200.0     20   japan  202001
# 1  banana  300.0     30   japan  202001
# 2  orange  150.0     40   japan  202001
# 3   apple  200.0     20   japan  202002
# 4  banana  300.0     40   japan  202002
# 5  orange  150.0     30   japan  202002
# 6   apple  200.0     20   japan  202003
# 7  banana  300.0     50   japan  202003
# 8  orange  150.0     10   japan  202003

2020年12月21日