2 回答

TA貢獻1803條經驗 獲得超6個贊
您可以np.where為此使用:
wa = 0.2*df.A + 0.4*df.B + 0.2*df.C
df['new_col'] = np.where(df.isna().any(axis=1), df.mean(axis=1), wa)
例子
df = pd.DataFrame({'A':[1,2,3],'B':[4,5,6], 'C':[7,8,np.nan]})
A B C
0 1 4 7.0
1 2 5 8.0
2 3 6 NaN
wa = 0.2*df.A + 0.4*df.B + 0.2*df.C
df['new_col'] = np.where(df.isna().any(axis=1), df.mean(axis=1), wa)
A B C new_col
0 1 4 7.0 3.2
1 2 5 8.0 4.0
2 3 6 NaN 4.5
細節
np.where將根據條件的結果在平均值或加權平均值中進行選擇has_nans:
df.assign(has_nans = df.isna().any(axis=1), mean=df.mean(axis=1), weighted_av = wa)
A B C new_col has_nans mean weighted_av
0 1 4 7.0 3.2 False 3.80 3.2
1 2 5 8.0 4.0 False 4.75 4.0
2 3 6 NaN 4.5 True 4.50 NaN

TA貢獻1829條經驗 獲得超13個贊
我正要寫與 yatu基本相同的答案,但試圖提高效率。
import pandas as pd
import numpy as np
df = pd.DataFrame({'A':[1,2,3],
'B':[4,5,6],
'C':[7,8,np.nan],
'D':[1, np.nan, np.nan]})
weights = np.array([0.2,0.4,0.2,0.2])
df["w_avg"]= np.where(df.isnull().any(1),
df.mean(1),
np.dot(df.values, weights))
鑒于沒有必要計算您不會使用的東西。
使用虛擬 dfnp.dot代替wa手動計算在速度和泛化方面更好
n = 5000
df = pd.DataFrame({"A":np.random.rand(n),
"B": np.random.rand(n),
"C":np.random.rand(n),
"D":np.random.rand(n)})
%%timeit
wa = 0.2*df.A + 0.4*df.B + 0.2*df.C + 0.2* df.D
735 μs ± 19.7 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
wa = np.dot(df.values, weights)
18.9 μs ± 732 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
添加回答
舉報