本博客为《利用Python进行数据分析》的读书笔记,请勿转载用于其他商业用途。
pandas对象装配了一个常用数字、统计学方法的集合。其中大部分属于归约 或汇总统计 的类别,这些方法从DataFrame的行或列中抽取一个Series或一系列值的单个值(如总和或平均值)。与NumPy数组中的类似方法相比,他们内建了处理缺失值的功能。考虑一个小型DataFrame:
df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5],
[np.nan, np.nan], [0.75, -1.3]],
index=['a', 'b', 'c', 'd'],
columns=['one', 'two'])
print(df)
#
one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3
调用DataFrame的sum
方法返回一个包含列上加和的Series:
print(df.sum())
#
one 9.25
two -5.80
dtype: float64
传入axis='columns'
或axis=1
,则会将一行上各个列的值相加:
print(df.sum(axis='columns'))
#
a 1.40
b 2.60
c 0.00
d -0.55
dtype: float64
除非整个切片上(在本例中是行或列)都是NA,否则NA值是被自动排除的。可以通过禁用skipna
来实现不排除NA值:
print(df.mean(axis='columns', skipna=False))
#
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
归约方法可选参数
方法 | 描述 |
---|---|
axis | 规约轴,0为行向,1为列向 |
skipna | 排除缺失值,默认为True |
level | 如果轴是多层索引的(MultiIndex),该参数可以缩减分组层级 |
一些方法,比如idxmin
和idxmax
,返回的是间接统计信息,比如最小值或最大值的索引值:
print(df.idxmax())
#
one b
two d
dtype: object
除了归约方法外,有的方法是积累型 方法:
print(df.cumsum())
#
one two
a 1.40 NaN
b 8.50 -4.5
c NaN NaN
d 9.25 -5.8
还有一类方法既不是归约型方法也不是累积型方法。describe
就是其中之一,它一次性产生多个汇总统计:
print(df.describe())
#
one two
count 3.000000 2.000000
mean 3.083333 -2.900000
std 3.493685 2.262742
min 0.750000 -4.500000
25% 1.075000 -3.700000
50% 1.400000 -2.900000
75% 4.250000 -2.100000
max 7.100000 -1.300000
对于非数值类型数据,describe
产生另一种汇总统计:
obj = pd.Series(['a', 'b', 'c', 'd'] * 4)
print(obj)
print(obj.describe())
#
0 a
1 b
2 c
3 d
4 a
5 b
6 c
7 d
8 a
9 b
10 c
11 d
12 a
13 b
14 c
15 d
dtype: object
count 16
unique 4
top a
freq 4
dtype: object
以下是汇总统计及其相关方法的完整列表。
描述性统计和汇总列表
方法 | 描述 |
---|---|
count | 非NA值的个数 |
describe | 计算Series或DataFrame各列的汇总统计集合 |
min,max | 计算最小值、最大值 |
argmin,argmax | 分别计算最小值、最大值所在的索引位置(整数) |
dixmin,idxmax | 分别计算最小值或最大值所在的索引标签 |
quantile | 计算样本的从0到1的分位数 |
sum | 加和 |
mean | 均值 |
median | 中位数(50%分位数) |
mad | 平均值的平均绝对偏差 |
prod | 所有值的积 |
var | 值的样本方差 |
std | 值的样本标准差 |
skew | 样本偏度(第三时刻)值 |
kurt | 样本峰度(第四时刻)值 |
cumsum | 累计值 |
cummin,cummax | 累计值的最小值或最大值 |
cumprod | 值的累计积 |
diff | 计算第一个算数差值(对时间序列有用) |
pct_change | 计算百分比 |
略
另一类相关的方法可以从一维Series包含的数值中提取信息。
obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
uniques = obj.unique()
print(uniques)
#
['c' 'a' 'd' 'b']
唯一值并不一定按照排序好的顺序返回,但是如果需要的话可以进行排序(uniques.sort()
)。相应地,value_count
计算Series包含的值的个数:
print(obj.value_counts())
#
a 3
c 3
b 2
d 1
dtype: int64
为了方便,返回的Series会按照数量降序排序。value_counts
也是有效的pandas顶层方法,可以用于任意数组或序列:
print(pd.value_counts(obj.values, sort=True))
#
c 3
a 3
b 2
d 1
dtype: int64
isin执行向量化的成员属性检查,还可以将数据集以Series或DataFrame一列的形式过滤为数据集的值子集:
print(obj)
#
0 c
1 a
2 d
3 a
4 a
5 b
6 b
7 c
8 c
dtype: object
mask = obj.isin(['b', 'c'])
print(mask)
#
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool
print(obj[mask])
#
0 c
5 b
6 b
7 c
8 c
dtype: object
与isin
相关的Index.get_indexer
方法,可以提供一个索引数组,这个索引数组可以将可能非唯一值数组转换为另一个唯一值数组:
to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
unique_vals = pd.Series(['c', 'b', 'a'])
print(pd.Index(unique_vals).get_indexer(to_match))
#
[0 2 1 1 0 2]
表:唯一值、计数和集合成员属性方法
方法 | 描述 |
---|---|
isin | 计算表征Series中每个值是否包含于传入序列的布尔值数组 |
match | 计算数组中每个值的整数索引,形成一个唯一值数组。有助于数据对齐和join类型的操作 |
unique | 计算Series值中的唯一值数组,按照观察顺序返回 |
value_counts | 返回一个Series,索引是唯一序列值,值是计数个数,按照个数降序排序 |
某些情况下,我们可能想要计算DataFrame多个相关列的直方图,如:
data = pd.DataFrame({
'Qu1': [1, 3, 4, 3, 4],
'Qu2': [2, 3, 1, 2, 3],
'Qu3': [1, 5, 2, 4, 4]})
print(data)
#
Qu1 Qu2 Qu3
0 1 2 1
1 3 3 5
2 4 1 2
3 3 2 4
4 4 3 4
将pandas.value_counts
传入DataFrame的apply
函数可以得到:
result = data.apply(pd.value_counts).fillna(0)
print(result)
#
Qu1 Qu2 Qu3
1 1.0 1.0 1.0
2 0.0 2.0 1.0
3 2.0 2.0 0.0
4 2.0 0.0 2.0
5 0.0 0.0 1.0
这里,结果中的行标签是所有列中出现的不同值,数值则是这些不同值在每个列中出现的次数。