我有一個如下所示的資料框。
d = {'location': ['a', 'a', 'b', 'b'], 'value': [1, 5, 3, 7], 'weight': [0.9, 0.1, 0.8, 0.2]}
df = pd.DataFrame(data=d)
df
location value weight
0 a 1 0.9
1 a 5 0.1
2 b 3 0.8
3 b 7 0.2
我目前有代碼可以計算未加權資料的分組中位數、標準偏差、偏斜和分位數,我正在使用以下代碼:
df = df[['location','value']]
df1 = df.groupby('location').agg(['median','skew','std']).reset_index()
df2 = df.groupby('location').quantile([0.1, 0.9, 0.25, 0.75, 0.5]).unstack(level=1).reset_index()
dfs = df1.merge(df2, how = 'left', on = 'location')
結果如下:
location value
median skew std 0.1 0.9 0.25 0.75 0.5
0 a 3 NaN 2.828427 1.4 4.6 2.0 4.0 3.0
1 b 5 NaN 2.828427 3.4 6.6 4.0 6.0 5.0
我想生成與上面完全相同的結果資料框,但是使用列進行加權統計weight。我該怎么做呢?
uj5u.com熱心網友回復:
不要合并兩個groupby操作,而是在對值加權后使用命名聚合:
- 生成
weighted使用值assign。 - 使用
{output_col: (input_col, agg_function), ...}.
dfs = df.assign(weighted=df.value * df.weight).groupby('location').agg(**{
'median': ('weighted', 'median'),
'skew': ('weighted', 'skew'),
'std': ('weighted', 'std'),
'0.1': ('weighted', lambda x: x.quantile(0.1)),
'0.9': ('weighted', lambda x: x.quantile(0.9)),
'0.25': ('weighted', lambda x: x.quantile(0.25)),
'0.75': ('weighted', lambda x: x.quantile(0.75)),
'0.5': ('weighted', lambda x: x.quantile(0.5)),
})
輸出:
median skew std 0.1 0.9 0.25 0.75 0.5
location
a 0.7 NaN 0.282843 0.54 0.86 0.60 0.80 0.7
b 1.9 NaN 0.707107 1.50 2.30 1.65 2.15 1.9
uj5u.com熱心網友回復:
為觀察添加權重的最準確方法是根據它們的權重復制觀察。
調整權重
在復制之前,您需要先調整權重,因為它們還不是整數。這是一個可以幫助您調整權重的功能。
def adjust(weights):
base = 10**max([len(str(i).split(".")[1]) for i in weights])
scalar = base / np.gcd.reduce((weights * base).astype(int))
weights = weights * scalar
return weights
如果你想知道這個函式是如何作業的,你可以參考我的問題。
- 將 Numpy 陣列乘以標量,使每個元素都是整數
df = pd.DataFrame({
"location": ["a", "a", "b", "b"],
"value": [1, 5, 3, 7],
"weights": [0.9, 0.1, 0.8, 0.2]
})
df.loc[:, "weights"] = adjust(df["weights"])
這是調整后的權重。
>>> df
location value weights
0 a 1 9.0
1 a 5 1.0
2 b 3 8.0
3 b 7 2.0
重復觀察
調整權重后,您需要根據它們的權重復制觀察。
df = df.loc[df.index.repeat(df["weights"])] \
.reset_index(drop=True).drop("weights", axis=1)
您可以參考這個優秀的答案來了解它是如何作業的。
- 根據列中的值重復行
讓我們計算重復后的觀察次數。
>>> df.count()
location 20
value 20
執行統計操作
現在,您可以使用groupby任何統計操作來使用和聚合。現在對資料進行加權。
df1 = df.groupby("location").agg(["median","skew","std"]).reset_index()
df2 = df.groupby("location").quantile([0.1, 0.9, 0.25, 0.75, 0.5]) \
.unstack(level=1).reset_index()
print(df1.merge(df2, how="left", on="location"))
這給出了以下輸出。
location value
median skew std 0.1 0.9 0.25 0.75 0.5
0 a 1.0 3.162278 1.264911 1.0 1.4 1.0 1.0 1.0
1 b 3.0 1.778781 1.686548 3.0 7.0 3.0 3.0 3.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/343405.html
