我試圖理解為什么會在資料框中發生這種情況
import pandas as pd
import numpy as np
#from pyspark.sql import SparkSession
#spark = SparkSession.builder.getOrCreate()
df = pd.DataFrame({"calories": [400, 200, 220, 70000, 500, 200, 300, 200, 100, 100, 100, 200, 300, 100, 200, 300, 400, 500, 100]})
q_low = df["calories"].quantile(0.01)
q_hi = df["calories"].quantile(0.99)
lb = df.quantile(0.01)
ub = df.quantile(0.99)
#replaces outliers with nan
df_filtered = df[(df < ub) & (df > lb)]
#removes outliers
df_filtered = df[(df["calories"] < q_hi) & (df["calories"] > q_low)]
print(df_filtered)
第一個 df_filtered 將所有例外值設定為 NaN,而第二個 df_filtered 將洗掉所有例外值。這兩個操作之間的功能區別是什么?為什么第一個將例外值設定為 NaN,而第二個只是洗掉它們?
uj5u.com熱心網友回復:
這是一個非常微妙的區別和一個有趣的帖子!太棒了。
這些結果不同的原因是在行
df_filtered = df[(df < ub) & (df > lb)]
您實際上是在嘗試通過布林值的DataFrame進行子集化。它是一個單列 DataFrame,而不是一個系列。那是,
type((df < ub) & (df > lb))
給pandas.core.frame.DataFrame.
在第二種情況下,
df_filtered = df[(df["calories"] < q_hi) & (df["calories"] > q_low)]
你是一個布爾系列的子集,我們可以通過呼叫再次檢查
type((df["calories"] < q_hi) & (df["calories"] > q_low))
這給出了pandas.core.series.Series.
當您通過布爾系列創建 DataFrame 時,您將洗掉與False系列中的值相對應的行。當您嘗試通過布爾 DataFrame 進行子集化時,您只會使任何與False值對應的元素變為NaNs。
當您開始查看具有多列的 DataFrame 時,這種行為是有意義的。考慮玩具 DataFrame df,:
calories calories
0 400.0 401.0
1 200.0 201.0
2 220.0 221.0
我們可以將整個 DataFrame 與單個值進行比較,但是洗掉整列或整行是沒有意義的,因為一個值不符合我們的條件。因此,任何不滿足條件的值都會設定為 NaN,如
df[df < 401]
給予
calories calories
0 400.0 NaN
1 200.0 201.0
2 220.0 221.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/494411.html
