书接上文~~
函数运用和映射
numpy的通用函数也能够对pandas目标操作:
In [190]: frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
.....: index=['Utah', 'Ohio', 'Texas', 'Oregon'])
In [191]: frame
Out[191]:
b d e
Utah -0.204708 0.478943 -0.519439
Ohio -0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 -1.296221
In [192]: np.abs(frame)
Out[192]:
b d e
Utah 0.204708 0.478943 0.519439
Ohio 0.555730 1.965781 1.393406
Texas 0.092908 0.281746 0.769023
Oregon 1.246435 1.007189 1.296221
另一个常见的操作是,将函数运用到由各列或行所形成的一维数组上。DataFrame的apply办法即可完成此功用:
In [193]: f = lambda x: x.max() - x.min()
In [194]: frame.apply(f)
Out[194]:
b 1.802165
d 1.684034
e 2.689627
dtype: float64
这儿的函数f,核算了一个Series的最大值和最小值的差,在frame的每列都执行了一次。成果是一个Series,运用frame的列作为索引。
假如传递axis=’columns’到apply,这个函数会在每行执行:
In [195]: frame.apply(f, axis='columns')
Out[195]:
Utah 0.998382
Ohio 2.521511
Texas 0.676115
Oregon 2.542656
dtype: float64
传递到apply的函数不是必须回来一个标量,还能够回来由多个值组成的Series:
In [196]: def f(x):
.....: return pd.Series([x.min(), x.max()], index=['min', 'max'])
In [197]: frame.apply(f)
Out[197]:
b d e
min -0.555730 0.281746 -1.296221
max 1.246435 1.965781 1.393406
排序和排名
排序一直都是数据中不行缺少的部分。要对行或列索引进行排序,能够运用sort_index
办法,它将回来一个现已排序的新目标:
In [201]: obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
In [202]: obj.sort_index()
Out[202]:
a 1
b 2
c 3
d 0
dtype: int64
上面是针对Series,当然关于DataFrame也有相似操作:
In [203]: frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
.....: index=['three', 'one'],
.....: columns=['d', 'a', 'b', 'c'])
In [204]: frame.sort_index()
Out[204]:
d a b c
one 4 5 6 7
three 0 1 2 3
In [205]: frame.sort_index(axis=1)
Out[205]:
a b c d
three 1 2 3 0
one 5 6 7 4
数据默许是按升序排序的,但也能够降序排序:
In [206]: frame.sort_index(axis=1, ascending=False)
Out[206]:
d c b a
three 0 3 2 1
one 4 7 6 5
若要按值对Series进行排序,可运用其sort_values办法:
In [207]: obj = pd.Series([4, 7, -3, 2])
In [208]: obj.sort_values()
Out[208]:
2 -3
3 2
0 4
1 7
dtype: int64
当排序一个DataFrame时,你或许期望依据一个或多个列中的值进行排序。将一个或多个列的姓名传递给sort_values的by选项即可达到该意图:
In [211]: frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
In [212]: frame
Out[212]:
a b
0 0 4
1 1 7
2 0 -3
3 1 2
In [213]: frame.sort_values(by='b')
Out[213]:
a b
2 0 -3
3 1 2
0 0 4
1 1 7
说完排序,接下来是排名,所谓排名就是指对数组从1到有效数据点总数分配名次的操作。Series和DataFrame的rank办法就是完成排名的函数办法。默许状况下,rank经过将平均排名分配到每个组来打破平级关系:
In [215]: obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
In [216]: obj.rank()
Out[216]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
简而言之就是对数据进行排大小。小的从1开始,大的在后,呈现重复的就取平均值。也能够依据值在原数据中呈现的次序给出排名:
In [217]: obj.rank(method='first')
Out[217]:
0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0
dtype: float64
这儿,条目0和2没有运用平均排名6.5,它们被设成了6和7,因为数据中标签0坐落标签2的前面。
当然你也能够倒序摆放,同样也能够在DataFrame中运用:
In [219]: frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
.....: 'c': [-2, 5, 8, -2.5]})
In [220]: frame
Out[220]:
a b c
0 0 4.3 -2.0
1 1 7.0 5.0
2 0 -3.0 8.0
3 1 2.0 -2.5
In [221]: frame.rank(axis='columns')
Out[221]:
a b c
0 2.0 3.0 1.0
1 1.0 3.0 2.0
2 2.0 1.0 3.0
3 2.0 3.0 1.0
图5-3展现了在排序中呈现平级(数值相同)的状况下如何区别先后的办法。
图5-3 破坏平级状况method值
带有重复标签的轴索引
当咱们的标签呈现重复的时候该怎么办?咱们来看看下面这个简略的带有重复索引值的Series:
In [222]: obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
In [223]: obj
Out[223]:
a 0
a 1
b 2
b 3
c 4
dtype: int64
索引的is_unique特点能够告知你它的值是否是仅有的:
In [224]: obj.index.is_unique
Out[224]: False
关于带有重复值的索引,数据选取的行为将会有些不同。假如某个索引对应多个值,则回来一个Series;而对应单个值的,则回来一个标量值:
In [225]: obj['a']
Out[225]:
a 0
a 1
dtype: int64
In [226]: obj['c']
Out[226]: 4
这样会使代码变复杂,因为索引的输出类型会依据标签是否有重复发生变化。对DataFrame的行进行索引时也是如此。所以咱们在运用中尽量避免轴索引重复的状况。
5.3描述性核算的概述与核算
pandas具有一组常用的数学和核算办法。其中大部分归于归约或汇总核算的分类。这些办法从DataFrame的行或列中抽取一个Series或一系列值的单个值(例如核算和或平均值)。与Numpy数组中的相似办法比较,它们内建了处理丢失值的功用。关于一个小型的DataFrame:
In [230]: 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'])
In [231]: df
Out[231]:
one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3
调用DataFrame的sum办法将会回来一个含有列的和的Series:
In [232]: df.sum()
Out[232]:
one 9.25
two -5.80
dtype: float64
传入axis=’columns’或axis=1将会按行进行求和运算:
In [233]: df.sum(axis=1)
Out[233]:
a 1.40
b 2.60
c NaN
d -0.55
NA值会自动被扫除,除非整个切片(这儿指的是行或列)都是NA。经过skipna选项能够禁用该功用:
In [234]: df.mean(axis='columns', skipna=False)
Out[234]:
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
下图5-4 列出了归约办法的常用参数
图5-4 归约办法的常用参数
还有很多办法就不逐个展现,下图5-5 展现了汇总核算相关办法的列表展现。
图5-5 核算办法列表
相关性和协方差
汇总核算,例如有相关性和协方差,这些都是很多个参数核算出来的。咱们来看一个实践的数据例子,它们来自Yahoo!Finance的股票价格和成交量,这儿的数据集有需求能够找我私信拿:
In [240]: price = pd.read_pickle('examples/yahoo_price.pkl')
In [241]: volume = pd.read_pickle('examples/yahoo_volume.pkl')
In [242]: returns = price.pct_change()
In [243]: returns.tail()
Out[243]:
AAPL GOOG IBM MSFT
Date
2016-10-17 -0.000680 0.001837 0.002072 -0.003483
2016-10-18 -0.000681 0.019616 -0.026168 0.007690
2016-10-19 -0.002979 0.007846 0.003583 -0.002255
2016-10-20 -0.000512 -0.005652 0.001719 -0.004867
2016-10-21 -0.003930 0.003011 -0.012474 0.042096
此处核算了数据价格中的百分比占比。
Series的corr办法用于核算两个Series中堆叠的、非NA的、按索引对齐的值的相关系数。与此相似,cov用于核算协方差:
In [244]: returns['MSFT'].corr(returns['IBM'])
Out[244]: 0.49976361144151144
In [245]: returns['MSFT'].cov(returns['IBM'])
Out[245]: 8.8706554797035462e-05
因为MSTF是一个合理的Python特点,咱们还能够用更简练的语法挑选列:
In [246]: returns.MSFT.corr(returns.IBM)
Out[246]: 0.49976361144151144
另一方面,DataFrame的corr和cov办法将以DataFrame的形式分别回来完整的相关系数或协方差矩阵:
In [247]: returns.corr()
Out[247]:
AAPL GOOG IBM MSFT
AAPL 1.000000 0.407919 0.386817 0.389695
GOOG 0.407919 1.000000 0.405099 0.465919
IBM 0.386817 0.405099 1.000000 0.499764
MSFT 0.389695 0.465919 0.499764 1.000000
In [248]: returns.cov()
Out[248]:
AAPL GOOG IBM MSFT
AAPL 0.000277 0.000107 0.000078 0.000095
GOOG 0.000107 0.000251 0.000078 0.000108
IBM 0.000078 0.000078 0.000146 0.000089
MSFT 0.000095 0.000108 0.000089 0.000215
使用DataFrame的corrwith办法,你能够核算其列或行跟另一个Series或DataFrame之间的相关系数。传入一个Series将会回来一个相关系数值Series(针对各列进行核算):
In [249]: returns.corrwith(returns.IBM)
Out[249]:
AAPL 0.386817
GOOG 0.405099
IBM 1.000000
MSFT 0.499764
dtype: float64
传入一个DataFrame则会核算按列名配对的相关系数。这儿,我核算百分比变化与成交量的相关系数:
In [250]: returns.corrwith(volume)
Out[250]:
AAPL -0.075565
GOOG -0.007067
IBM -0.204849
MSFT -0.092950
dtype: float64
传入axis=’columns’即可按行进行核算。无论如何,在核算相关系数之前,一切的数据项都会按标签对齐。
仅有值、计数和成员特点
另一类办法就是在从一维的Series包括的数值中提取信息。为了阐明简略,下面举个例子:
In [251]: obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
第一个函数是unique,它能够得到Series中的仅有值数组:
In [252]: uniques = obj.unique()
In [253]: uniques
Out[253]: array(['c', 'a', 'd', 'b'], dtype=object)
回来的仅有值是未排序的,假如需求的话,能够对成果再次进行排序(uniques.sort())。相似的,value_counts用于核算一个Series中各值呈现的频率:
In [254]: obj.value_counts()
Out[254]:
c 3
a 3
b 2
d 1
dtype: int64
为了便于查看,成果Series是按值频率降序摆放的。value_counts还是一个尖端pandas办法,可用于任何数组或序列:
In [255]: pd.value_counts(obj.values, sort=False)
Out[255]:
a 3
b 2
c 3
d 1
dtype: int64
isin用于判别矢量化调集的成员资格,可用于过滤Series中或DataFrame列中数据的子集:
In [256]: obj
Out[256]:
0 c
1 a
2 d
3 a
4 a
5 b
6 b
7 c
8 c
dtype: object
In [257]: mask = obj.isin(['b', 'c'])
In [258]: mask
Out[258]:
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool
In [259]: obj[mask]
Out[259]:
0 c
5 b
6 b
7 c
8 c
dtype: object
与isin相似的是Index.get_indexer办法,它能够给你一个索引数组,从或许包括重复值的数组到另一个不同值的数组:
In [260]: to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
In [261]: unique_vals = pd.Series(['c', 'b', 'a'])
In [262]: pd.Index(unique_vals).get_indexer(to_match)
Out[262]: array([0, 2, 1, 1, 0, 2])
图5-6 给出了这几个办法的一些参阅信息。
图5-6 常见办法参阅
总结
本章就大约这样,鄙人一章,咱们将讨论用pandas读取(或加载)和写入数据集的东西。之后,咱们将更深入地研讨运用pandas进行数据清洗、规整、分析和可视化东西。