返回介绍

5.3 Summarizing and Computing Descriptive Statistics 汇总和描述性统计

发布于 2023-07-20 22:48:05 字数 11434 浏览 0 评论 0 收藏 0

pandas 有很多数学和统计方法。大部分可以归类为降维或汇总统计,这些方法是用来从 series 中提取单个值(比如 sum 或 mean)。还有一些方法来处理缺失值:

import pandas as pd
import numpy as np
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'])
df
 onetwo
a1.40NaN
b7.10-4.5
cNaNNaN
d0.75-1.3

使用 sum 的话,会返回一个 series:

df.sum()
one    9.25
two   -5.80
dtype: float64

使用 axis='columns' or axis=1 ,计算列之间的和:

df.sum(axis='columns')
a    1.40
b    2.60
c    0.00
d   -0.55
dtype: float64

计算的时候,NA(即缺失值)会被除外,除非整个切片全是 NA。我们可以用 skipna 来跳过计算 NA:

df.mean(axis='columns', skipna=False)
a      NaN
b    1.300
c      NaN
d   -0.275
dtype: float64

一些方法,比如 idxmin 和 idxmax,能返回间接的统计值,比如 index value:

df
 onetwo
a1.40NaN
b7.10-4.5
cNaNNaN
d0.75-1.3
df.idxmax()
one    b
two    d
dtype: object

还能计算累加值:

df.cumsum()
 onetwo
a1.40NaN
b8.50-4.5
cNaNNaN
d9.25-5.8

另一种类型既不是降维,也不是累加。describe 能一下子产生多维汇总数据:

df.describe()
onetwo
count3.0000002.000000
mean3.083333-2.900000
std3.4936852.262742
min0.750000-4.500000
25%NaNNaN
50%NaNNaN
75%NaNNaN
max7.100000-1.300000

对于非数值性的数据,describe 能产生另一种汇总统计:

obj = pd.Series(['a', 'a', 'b', 'c'] * 4)
obj
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
obj.describe()
count     16
unique     3
top        a
freq       8
dtype: object

1 Correlation and Covariance (相关性和协方差)

假设 DataFrame 时股价和股票数量。这些数据取自 yahoo finace,用 padas-datareader 包能加载。如果没有的话,用 conda 或 pip 来下载这个包:

conda install pandas-datareader
import pandas_datareader.data as web
all_data = {ticker: web.get_data_yahoo(ticker)
            for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']}

price = pd.DataFrame({ticker: data['Adj Close']
                      for ticker, data in all_data.items()})

volumn = pd.DataFrame({ticker: data['Volumn']
                       for ticker, data in all_data.items()})

上面的代码无法直接从 yahoo 上爬取数据,因为 yahoo 被 verizon 收购后,好像是不能用了。于是这里我们直接从下好的数据包里加载。

ls ../examples/
5.1 Introduction to pandas Data Structures(pandas 的数据结构).ipynb

5.2 Essential Functionality(主要功能).ipynb

5.3 Summarizing and Computing Descriptive Statistics(总结和描述性统计).ipynb

price = pd.read_pickle('../examples/yahoo_price.pkl')
volume = pd.read_pickle('../examples/yahoo_volume.pkl')
price.head()
 AAPLGOOGIBMMSFT
Date    
2010-01-0427.990226313.062468113.30453625.884104
2010-01-0528.038618311.683844111.93582225.892466
2010-01-0627.592626303.826685111.20868325.733566
2010-01-0727.541619296.753749110.82373225.465944
2010-01-0827.724725300.709808111.93582225.641571
volume.head()
 AAPLGOOGIBMMSFT
Date    
2010-01-041234324003927000615530038409100
2010-01-051504762006031900684140049749600
2010-01-061380400007987100560530058182400
2010-01-0711928280012876600584060050559700
2010-01-081119027009483900419720051197400

pct_change(): 这个函数用来计算同 colnums 两个相邻的数字之间的变化率

现在我们计算一下价格百分比的变化:

returns = price.pct_change()
returns.tail()
 AAPLGOOGIBMMSFT
Date    
2016-10-17-0.0006800.0018370.002072-0.003483
2016-10-18-0.0006810.019616-0.0261680.007690
2016-10-19-0.0029790.0078460.003583-0.002255
2016-10-20-0.000512-0.0056520.001719-0.004867
2016-10-21-0.0039300.003011-0.0124740.042096

series 的 corr 方法计算两个,重合的,非 NA 的,通过 index 排列好的 series。cov 计算方差:

returns['MSFT'].corr(returns['IBM'])
0.4997636114415116
returns['MSFT'].cov(returns['IBM'])
8.8706554797035489e-05

因为 MSFT 是一个有效的 python 属性,我们可以通过更简洁的方式来选中 columns:

returns.MSFT.corr(returns.IBM)
0.4997636114415116

dataframe 的 corr 和 cov 方法,能返回一个完整的相似性或方差矩阵:

returns.corr()
 AAPLGOOGIBMMSFT
AAPL1.0000000.4079190.3868170.389695
GOOG0.4079191.0000000.4050990.465919
IBM0.3868170.4050991.0000000.499764
MSFT0.3896950.4659190.4997641.000000
returns.cov()
 AAPLGOOGIBMMSFT
AAPL0.0002770.0001070.0000780.000095
GOOG0.0001070.0002510.0000780.000108
IBM0.0000780.0000780.0001460.000089
MSFT0.0000950.0001080.0000890.000215

用 Dataframe 的 corrwith 方法,我们可以计算 dataframe 中不同 columns 之间,或 row 之间的相似性。传递一个 series:

returns.corrwith(returns.IBM)
AAPL    0.386817
GOOG    0.405099
IBM     1.000000
MSFT    0.499764
dtype: float64

传入一个 dataframe 能计算匹配的 column names 质监局的相似性。这里我计算 vooumn 中百分比变化的相似性:

returns.corrwith(volume)
AAPL   -0.075565
GOOG   -0.007067
IBM    -0.204849
MSFT   -0.092950
dtype: float64

传入 axis='columns'能做到 row-by-row 计算。在 correlation 被计算之前,所有的数据会根据 label 先对齐。

2 Unique Values, Value Counts, and Membership(唯一值,值计数,会员)

这里介绍另一种从一维 series 中提取信息的方法:

obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])

第一个函数时 unique,能告诉我们 series 里 unique values 有哪些:

uniques = obj.unique()
uniques
array(['c', 'a', 'd', 'b'], dtype=object)

返回的 unique values 不是有序的,但我们可以排序,uniques.sort()。相对的,value_counts 能计算 series 中值出现的频率:

obj.value_counts()
a    3
c    3
b    2
d    1
dtype: int64

返回的结果是按降序处理的。vaule_counts 也是 pandas 中的方法,能用在任何 array 或 sequence 上:

pd.value_counts(obj.values, sort=False)
d    1
c    3
b    2
a    3
dtype: int64

isin 能实现一个向量化的集合成员关系检查,能用于过滤数据集,检查一个子集,是否在 series 的 values 中,或在 dataframe 的 column 中:

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'])
mask
0     True
1    False
2    False
3    False
4    False
5     True
6     True
7     True
8     True
dtype: bool
obj[mask]
0    c
5    b
6    b
7    c
8    c
dtype: object

与 isin 相对的另一个方法是 Index.get_indexer,能返回一个 index array,告诉我们有重复值的 values(to_match),在非重复的 values(unique_vals)中对应的索引值:

to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
unique_vals = pd.Series(['c', 'b', 'a'])
pd.Index(unique_vals).get_indexer(to_match)
array([0, 2, 1, 1, 0, 2])

在某些情况下,你可能想要计算一下 dataframe 中多个 column 的柱状图:

data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],
                     'Qu2': [2, 3, 1, 2, 3],
                     'Qu3': [1, 5, 2, 4, 4]})
data
 Qu1Qu2Qu3
0121
1335
2412
3324
4434

把 padas.value_counts 传递给 dataframe 的 apply 函数:

result = data.apply(pd.value_counts)
result
 Qu1Qu2Qu3
11.01.01.0
2NaN2.01.0
32.02.0NaN
42.0NaN2.0
5NaNNaN1.0

每一行的 laebls(即 1,2,3,4,5)其实就是整个 data 里出现过的值,从 1 到 5。而对应的每个方框里的值,则是表示该值在当前列中出现的次数。比如,(2, Qu1)的值是 Nan,说明 2 这个数字没有在 Qu1 这一列出现过。(2, Qu2)的值是 2,说明 2 这个数字在 Qu2 这一列出现过 2 次。(2, Qu3)的值是 1,说明 2 这个数字在 Qu3 这一列出现过 1 次。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文