1. 程式人生 > 其它 >按照A列進行分組並計算出B列每個分組的平均值,然後對B列內的每個元素減去分組平均值

按照A列進行分組並計算出B列每個分組的平均值,然後對B列內的每個元素減去分組平均值

大家好,我是皮皮。

一、前言

前幾天在Python星耀交流群有個叫【在下不才】的粉絲問了一個Pandas的問題,按照A列進行分組並計算出B列每個分組的平均值,然後對B列內的每個元素減去分組平均值,這裡拿出來給大家分享下,一起學習。

二、解決過程

這個看上去倒是不太難,但是實現的時候,總是一看就會,一用就廢。這裡給出【瑜亮老師】的三個解法,一起來看看吧!

方法一:使用自定義函式

程式碼如下:

import pandas as pd

lv = [1, 2, 2, 3, 3, 4, 2, 3, 3, 3, 3]
num = [122, 111, 222, 444, 555, 555, 333, 666, 666, 777, 888]
df = pd.DataFrame({'lv': lv, 'num': num})

def demean(arr):
    return arr - arr.mean()
# 按照"lv"列進行分組並計算出"num"列每個分組的平均值,然後"num"列內的每個元素減去分組平均值
df["juncha"] = df.groupby("lv")["num"].transform(demean)
print(df

# transform 也支援 lambda 函式,效果是一樣的,更簡潔一些
# df["juncha"] = df.groupby("lv")["num"].transform(lambda x: x - x.mean())
# print(df)

方法二:使用內建函式

程式碼如下:

import pandas as pd

lv = [1, 2, 2, 3, 3, 4, 2, 3, 3, 3, 3]
num = [122, 111, 222, 444, 555, 555, 333, 666, 666, 777, 888]
df = pd.DataFrame({'lv': lv, 'num': num})

gp_mean = df.groupby('lv')["num"].mean().rename("gp_mean").reset_index()
df2 = df.merge(gp_mean)
df2["juncha"] = df2["num"] - df2["gp_mean"]
print(df2)

方法三:使用 transform

transform能返回完整資料,輸出的形狀和輸入一致(輸入是num列,輸出也是一列),程式碼如下:

import pandas as pd

lv = [1, 2, 2, 3, 3, 4, 2, 3, 3, 3, 3]
num = [122, 111, 222, 444, 555, 555, 333, 666, 666, 777, 888]
df = pd.DataFrame({'lv': lv, 'num': num})

# 方法三: 使用 transform。
df["gp_mean"] = df.groupby('lv')["num"].transform('mean')
df["juncha"] = df["num"] - df["gp_mean"]
print(df)
# 直接輸出結果,省略分組平均值列
df["juncha"] = df["num"] - df.groupby('lv')["num"].transform('mean')
print(df)

這樣問題就完美地解決啦!

後面他還想用類的方式寫,不過看上去沒有那麼簡單。

三、總結

大家好,我是皮皮。這篇文章主要分享了Pandas處理相關知識,基於粉絲提出的按照A列進行分組並計算出B列每個分組的平均值,然後對B列內的每個元素減去分組平均值的問題,給出了3個行之有效的方法,幫助粉絲順利解決了問題。

最後感謝粉絲【在下不才】提問,感謝【德善堂小兒推拿-瑜亮老師】給出的具體解析和程式碼演示,感謝【月神】提供的思路,感謝【dcpeng】等人蔘與學習交流。

小夥伴們,快快用實踐一下吧!如果在學習過程中,有遇到任何問題,歡迎加我好友,我拉你進Python學習交流群共同探討學習。