本系列文章配套代码获取有以下三种途径:
-
可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):
https://returu.github.io/Python_Data_Analysis/lab/index.html
-
也可以通过百度网盘获取,需要在本地配置代码运行环境,环境配置可以查看【Python基础】2.搭建Python开发环境:
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj
提取码:mnsj
-
前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis
根据《Python for Data Analysis 3rd Edition》翻译整理
—————————————————–
聚合()是指所有根据数组产生标量值的数据转换过程。包括之前使用到的mean
, count
, min
, sum
等。
下面是一些优化的groupby
方法:
函数名 |
说明 |
any, all | 如果任何(一个或多个值)或所有非 NA 值都是“真实的”,则返回 True |
count | 非 NA 值的数量 |
cummin, cummax | 非 NA 值的最小和最大累积值 |
cumsum | 非 NA 值的累积和 |
cumprod | 非 NA 值的累积积 |
first, last | 第一个和最后一个非 NA 值 |
mean | 非 NA 值的平均值 |
median | 非 NA 值的算术中位数 |
min, max | 非 NA 值的最小值和最大值 |
nth | 检索将出现在位置 n 的值,数据按排序顺序排列 |
ohlc | 为类似时间序列的数据计算四个“open-high-low-close”统计数据 |
prod | 非 NA 值的乘积 |
quantile | 计算样本分位数 |
rank | 非 NA 值的序数排名 |
size | 计算组大小,将结果作为Series返回 |
sum | 非 NA 值的总和 |
std, var | 样本标准差和方差 |
1>>> rng = np.random.default_rng(12345)
2
3>>> df = pd.DataFrame({"key1" : ["a", "a", None, "b", "b", "a", None],
4... "key2" : pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),
5... "data1" : np.round(rng.standard_normal(7) , 2),
6... "data2" : np.round(rng.standard_normal(7) , 2)})
7
8>>> df
9 key1 key2 data1 data2
100 a 1 -1.42 0.65
111 a 2 1.26 0.36
122 None 1 -0.87 -1.95
133 b 2 -0.26 2.35
144 b 1 -0.08 0.97
155 a <NA> -0.74 -0.76
166 None 1 -1.37 0.90
nsmallest
方法用于选择前n小的数据,虽然该方法并没有显式地为GroupBy对象实现,但它是Series的方法。在内部GroupBy对Series进行切片,为每一块调用 piece.nsmallest(n),然后将其组装到结果对象中。1>>> grouped = df.groupby("key1")
2
3>>> grouped["data1"].nsmallest(2)
4key1
5a 0 -1.42
6 5 -0.74
7b 3 -0.26
8 4 -0.08
9Name: data1, dtype: float64
自定义聚合函数通常比上面表中的优化函数慢得多。这是因为在构建中间组数据块时有一些额外的开销(函数调用、数据重排)。
1# 自定义函数,每列最大值-最小值
2>>> def peak_to_peak(arr):
3... return arr.max() - arr.min()
4
5
6>>> df.groupby("key1").agg(peak_to_peak)
7 key2 data1 data2
8key1
9a 1 2.68 1.41
10b 1 0.18 1.38
另外,某些方法(如 describe
)也是有效的,尽管严格来说它们不是聚合函数。
1>>> df.groupby("key1").describe()
2 key2 ... data2
3 count mean std min 25% 50% 75% max ... count mean std min 25% 50% 75% max
4key1 ...
5a 2.0 1.5 0.707107 1.0 1.25 1.5 1.75 2.0 ... 3.0 0.083333 0.744603 -0.76 -0.200 0.36 0.505 0.65
6b 2.0 1.5 0.707107 1.0 1.25 1.5 1.75 2.0 ... 2.0 1.660000 0.975807 0.97 1.315 1.66 2.005 2.35
7
8[2 rows x 24 columns]
2.逐列或多函数应用:
如上所述,对一个Series 或 DataFrame 的所有列进行聚合,就是使用aggregate
(或 agg
)和所需函数,或调用 mean
或 std
等方法。
但是,你可能希望根据列使用不同的函数或同时使用多个函数进行聚合。
对于上述表 中的描述性统计信息,可以将函数名称作为字符串传递。
1>>> df = pd.DataFrame({"key1" : ["a", "a", "b", "b", "a", "b"],
2... "key2" : pd.Series(["x", "y", "y", "x", "x", "y"]),
3... "data1" : [1, 2, 3, 4, 5, 6],
4... "data2" : [7, 8, 9, 10, 11, 12]})
5
6>>> df
7 key1 key2 data1 data2
80 a x 1 7
91 a y 2 8
102 b y 3 9
113 b x 4 10
124 a x 5 11
135 b y 6 12
14
15>>> df.groupby(["key1","key2"])["data1"].agg("mean")
16key1 key2
17a x 3.0
18 y 2.0
19b x 4.0
20 y 4.5
21Name: data1, dtype: float64
如果改为传递函数或函数名称的列表,则会返回一个 DataFrame,其中列名取自函数名。传递的这些函数会各自运用于数据分组。
1>>> df.groupby(["key1","key2"])["data1"].agg(["mean","std",peak_to_peak])
2 mean std peak_to_peak
3key1 key2
4a x 3.0 2.828427 4
5 y 2.0 NaN 0
6b x 4.0 NaN 0
7 y 4.5 2.121320 3
你可以不接受 GroupBy 对象给予各列的名称;值得注意的是,lambda 函数的名称为
1>>> df.groupby(["key1","key2"])["data1"].agg([("average", "mean"), ("stdev", np.std), ("Custom_Func", peak_to_peak)])
2 average stdev Custom_Func
3key1 key2
4a x 3.0 2.828427 4
5 y 2.0 NaN 0
6b x 4.0 NaN 0
7 y 4.5 2.121320 3
在 DataFrame 中有更多选择,可以指定一个函数列表以应用于所有列。
1>>> functions = ["count", "mean", "max"]
2>>> df.groupby(["key1","key2"]).agg(functions)
3 data1 data2
4 count mean max count mean max
5key1 key2
6a x 2 3.0 5 2 9.0 11
7 y 1 2.0 2 1 8.0 8
8b x 1 4.0 4 1 10.0 10
9 y 2 4.5 6 2 10.5 12
10
11# 也可以传递具有自定义名称的元组列表
12>>> ftuples = [("Average", "mean"), ("Custom_Func", peak_to_peak)]
13>>> df.groupby(["key1","key2"]).agg(ftuples)
14 data1 data2
15 Average Custom_Func Average Custom_Func
16key1 key2
17a x 3.0 4 9.0 4
18 y 2.0 0 8.0 0
19b x 4.0 0 10.0 0
20 y 4.5 3 10.5 3
aggregate
(或 agg
)。只有当多个函数应用于至少一列时,DataFrame 才会具有分层列。
1>>> df.groupby(["key1","key2"]).agg({"data1" : np.max, "data2" : "sum"})
2 data1 data2
3key1 key2
4a x 5 18
5 y 2 8
6b x 4 10
7 y 6 21
8
9
10>>> df.groupby(["key1","key2"]).agg({"data1" : ["min", "max", "mean", "std"],"data2" : [("Average", "mean"), ("Custom_Func", peak_to_peak)]})
11 data1 data2
12 min max mean std Average Custom_Func
13key1 key2
14a x 1 5 3.0 2.828427 9.0 4
15 y 2 2 2.0 NaN 8.0 0
16b x 4 4 4.0 NaN 10.0 0
17 y 3 6 4.5 2.121320 10.5 3
上述示例中,聚合数据返回时都有一个索引,有时是分层的,由唯一的分组键组成。
as_index=False
传递给 groupby
来禁用分组键作为索引的行为。 1>>> df.groupby(["key1","key2"]).mean()
2 data1 data2
3key1 key2
4a x 3.0 9.0
5 y 2.0 8.0
6b x 4.0 10.0
7 y 4.5 10.5
8
9>>> df.groupby(["key1","key2"] , as_index=False).mean()
10 key1 key2 data1 data2
110 a x 3.0 9.0
121 a y 2.0 8.0
132 b x 4.0 10.0
143 b y 4.5 10.5
本篇文章来源于微信公众号: 码农设计师