三、描述性统计的概述与计算
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:
df1 = df.sum()
print(df1)
---------------------------------------------------------
one 9.25
two -5.80
dtype: float64
传入axis = ’columns‘ 或 axis =1 ,则会将一行上各个列的值相加:
df2 = df.sum(axis=1)
print(df2)
---------------------------------------------------------
a 1.40
b 2.60
c 0.00
d -0.55
dtype: float64
可以通过禁用skipna来实现不排除NA值:
df3 = df.mean(axis='columns',skipna=False)
print(df3)
---------------------------------------------------------
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
下表是归约方法的常用可选参数列表:
| 方法 | 描述 |
|---|---|
| axis | 归约轴,0为行向,1为列向 |
| skipna | 排除缺失值 |
| level | 如果轴是多层索引的,该参数可以缩减分组层级 |
一些方法,比如idxmin和idxmax,返回的是间接统计信息,比如最小值或最大值的索引值:
one b
two d
dtype: object
除了归约方法外,有的方法是积累型方法:
df5 = df.cumsum()
print(df5)
---------------------------------------------------------
one two
a 1.40 NaN
b 8.50 -4.5
c NaN NaN
d 9.25 -5.8
还有一类方法既不是归约型也不是积累型方法》describe就是其中之一,它一次性产生多个汇总统计:
df6 = df.describe()
print(df6)
---------------------------------------------------------
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','a','b','c']*4)
print(obj)
df7 = obj.describe()
print(df7)
---------------------------------------------------------
0 a
1 a
2 b
3 c
4 a
5 a
6 b
7 c
8 a
9 a
10 b
11 c
12 a
13 a
14 b
15 c
dtype: object
count 16
unique 3
top a
freq 8
dtype: object
下表是汇总统计及其相关方法的完整列表:
| 方法 | 描述 |
|---|---|
| count | 非NA值的个数 |
| describe | 计算Series或DataFrame各列的汇总统计集合 |
| min,max | 计算最小值,最大值 |
| argmin,argmax | 分别计算最小值、最大值所在的索引位置(整数) |
| idxmin,idxmax | 分别计算最小值或最大值所在的索引标签 |
| quantile | 计算样本的从0到1间的分位数 |
| sum | 加和 |
| mean | 均值 |
| median | 中位数(50%分位数) |
| mad | 平均值的平均绝对偏差 |
| prod | 所有值的积 |
| var | 值的样本方差 |
| std | 值的样本标准差 |
| skew | 样本偏差(第三时刻)值 |
| kurt | 样本峰度(第四时刻)值 |
| cumsum | 累计值 |
| cummin,cummax | 累计值的最小值或最大值 |
| cumprod | 值的累计积 |
| diff | 计算第一个算术差值(对时间序列有用) |
| pct_change | 计算百分比 |
3.1 相关性和协方差
一些汇总统计,比如相关性和协方差,是由多个参数计算出的。在下列中:
df = pd.Series(np.random.randn(5))
print(df)
df1 = pd.Series([4.7,5.6,9.6,8.,1.2])
print(df1)
---------------------------------------------------------
0 0.926654
1 -0.454879
2 0.234394
3 1.235043
4 -1.895585
dtype: float64
0 4.7
1 5.6
2 9.6
3 8.0
4 1.2
dtype: float64
我们将介绍corr和cov方法,Series的corr方法计算的是两个Series中重叠的、非NA的、按索引对齐的值的相关性。相应的,cov计算的是协方差。
a1 = df.corr(df1)
print(a1)
a2 = df.cov(df1)
print(a2)
---------------------------------------------------------
0.7067807666496997
2.8495572605136714
另一方面,DataFrame的corr和cov方法会分别以DataFrame的形式返回相关性和协方差矩阵:
frame1 = frame.corr()
print(frame1)
frame1 = frame.cov()
print(frame1)
---------------------------------------------------------
AAPL GOOG IBM MSFT
AAPL 1.000000 0.812578 -0.557313 -0.827599
GOOG 0.812578 1.000000 -0.655483 -0.855886
IBM -0.557313 -0.655483 1.000000 0.813606
MSFT -0.827599 -0.855886 0.813606 1.000000
AAPL GOOG IBM MSFT
AAPL 0.941398 0.845447 -0.216934 -0.563761
GOOG 0.845447 1.149924 -0.281992 -0.644375
IBM -0.216934 -0.281992 0.160947 0.229162
MSFT -0.563761 -0.644375 0.229162 0.492920
使用DataFrame的corrwith方法,你可以计算出DataFrame中的行或列与另一个序列或DataFrame的相关性。该方法传入一个Series时,会返回一个含有为每列计算相关性值的Series:
frame = pd.DataFrame(np.random.randn(5, 4), columns=['AAPL', 'GOOG', 'IBM', 'MSFT'])
print(frame)
frame2 = frame.corrwith(frame['IBM'])
print(frame2)
---------------------------------------------------------
AAPL GOOG IBM MSFT
0 1.482156 -0.315742 -0.310517 0.722257
1 1.723575 0.395895 0.883944 0.266165
2 -0.373946 2.475489 1.693208 0.372700
3 -0.892074 -0.394421 -0.016023 -1.239578
4 -0.645072 -0.488317 0.114536 0.373224
AAPL -0.059864
GOOG 0.937608
IBM 1.000000
MSFT 0.188640
dtype: float64
传入一个DataFrame时,会计算匹配到列名的相关性数值。而传入axis = ‘columns’这里将不做示例。
3.2 唯一值、计数和成员属性
另一个相关方法可以从一维Series包含的数值中提取信息。可以参考下列例子:
obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
print(obj)
---------------------------------------------------------
0 c
1 a
2 d
3 a
4 a
5 b
6 b
7 c
8 c
dtype: object
函数unique,它会给出Series的唯一值:
uniques = obj.unique()
print(uniques)
---------------------------------------------------------
['c' 'a' 'd' 'b']
其中的唯一值顺序不定,如果需要的话可以使用uniques.sort()方法进行排序。相应地,value_counts计算Series包含的值的个数:
a1 = obj.value_counts()
print(a1)
---------------------------------------------------------
c 3
a 3
b 2
d 1
dtype: int64
返回的Series会按照数量降序排序。而value_counts也是有效的pandas顶层方法,可以用于任意数组或序列:
a2 = pd.value_counts(obj.values,sort=False)
print(a2)
---------------------------------------------------------
c 3
a 3
d 1
b 2
dtype: int64
isin执行向量化的成员属性检查,还可以将数据集以Series或DataFrame一列的形式过滤为数据集的值子集:
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
而mask也是布尔值数组型对象,因此可以当作索引传递给obj里:
a3 = obj[mask]
print(a3)
---------------------------------------------------------
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'])
a4 = pd.Index(unique_vals).get_indexer(to_match)
print(a4)
---------------------------------------------------------
[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
这里,结果中的行标签是所有列中出现的不同值,数值则是这些不同值在每个列中出现的次数。
总结
这里简单了介绍一些pandas的索引数组的建立和基本功能。这些内容都是从学习《利用Python进行数据分析》所记录的笔记。后面将会继续从这本书当中学习内容。

被折叠的 条评论
为什么被折叠?



