import pandas as pd
import numpy as np
data = {'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': np.random.randn(8),
'D': np.random.randn(8)}
df = pd.DataFrame(data)
def stats(group: pd.DataFrame) -> pd.DataFrame:
return pd.DataFrame({'mean': group['C'].mean(),
'std': group['C'].std()} , index=[0])
def stats1(group: pd.DataFrame) -> pd.Series:
return pd.Series({'mean': group['C'].mean(),
'std': group['C'].std()})
groupbyObj = df.groupby(['A', 'B'])
#<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001C377E62E80>
result = groupbyObj.apply(stats)
result1 = groupbyObj.apply(stats1)
result_agg = groupbyObj.agg(['mean', 'std'])
生成的df:
function stats():
參數為df
輸出一個僅有一列的DataFrame
兩個欄標籤為mean , std
function stats1():
參數為df
輸出一個Series
兩個index為mean , std
这里的 stats 函数返回的是一个 DataFrame,
其中 mean 和 std 是这个 DataFrame 的两个column,
每个分组返回一个row。
如果 stats 函数返回的是 Series,
那么在对 DataFrame 调用 apply 后
得到的结果也会是 Series 类型,
每个分组返回一个 Series。
放在.apply()中的function
return DataFrame or Series
效果皆一樣:
(其實result比result1多了一層index 0)
result_agg = groupbyObj.agg([‘mean’, ‘std’])
.agg()中放的聚合函數
一次只能处理一个column,并返回聚合结果。
通常,这些聚合函数将返回标量值,
例如平均值、总和或计数。
以上例子使用.apply()的話
自定義函式只有寫 group[‘C’]
因此只有算出C欄位的mean, std
groupbyObj.agg([‘mean’, ‘std’])
則自動對所有欄位做mean, std
.apply()要做到一樣效果的話
自定義函式就要再多寫group[‘D’]的運算:
要是欄位很多呢?
看起來.agg() 方便許多
但apply()中的自定義函式
參數為DataFrame
所以可以做跨欄運算
例如DF欄位有X Y,
可以return (X**2 + Y**2)**0.5
#直角座標轉換為極座標
這時候就只能使用.apply()
.apply()更灵活,可以处理更加复杂的逻辑,
尤其是对于跨列或跨行运算的情况。
然而,.agg()函数更适合进行基础的数据聚合操作,
同时它的性能也比.apply()更好。
对于每个具体的数据处理任务,
需要根据具体情况选择适合的函数。
在 groupby
的結果中,
每個組的組內資料被轉換為一個 DataFrame。
當使用 apply
時,
可以將每個組內的 DataFrame 作為參數傳遞給函數。
該函數可以返回一個 (一列的)DataFrame 或 Series,
(就算返回DataFrame,其實只有一列)
其中索引由原始 DataFrame 和組內索引組成。
當使用 agg
時,
將會對每個組內的 Series (單一column)執行單個操作,
這些操作可以是內置的,也可以是自定義的。
這些操作可以返回一個標量,
這些值將在輸出的結果 DataFrame 中對應到組的名稱。
因此,在 agg
函數中使用的函數需要針對 Series
而不是 DataFrame 進行操作。
推薦hahow線上學習python: https://igrape.net/30afN