一、Pandas的对齐运算
是数据清洗的重要过程,可以按索引对齐进行运算,如果没有对齐的位置补NAN,最后也可以填充NAN
1.1 算数运算与数据对齐
1.1.1 Series 数据对齐
import pandas as pd
import numpy as np
s1 = pd.Series(range(10,20),index=range(10))
s2 = pd.Series(range(20,25),index=range(5))
print('s1:\n',s1,'\n')
print('s2:\n',s2,'\n')
s1:
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
dtype: int64
s2:
0 20
1 21
2 22
3 23
4 24
dtype: int64
# 作算数运算会自动结合双方的index来对齐
print(s1 + s2)
0 30.0
1 32.0
2 34.0
3 36.0
4 38.0
5 NaN
6 NaN
7 NaN
8 NaN
9 NaN
dtype: float64
1.1.2 DataFrame数据对齐
df1 = pd.DataFrame(np.arange(12).reshape((4,3)),index = ['a','b','c','d'],columns=['A','B','C'])
df2 = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','d','f'],columns=['A','B','D'])
print(df1,'\n')
print(df2,'\n')
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 9 10 11
A B D
a 0 1 2
d 3 4 5
f 6 7 8
print(df1+df2)
A B C D
a 0.0 2.0 NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN
d 12.0 14.0 NaN NaN
f NaN NaN NaN NaN
1.2 使用填充值的算数方法
算数方法表:(r开头的的是反运算)
方法 | 描述 |
---|---|
add, radd | 加法(+) |
sub, rsub | 减法(-) |
div, rdiv | 除法(/) |
floordiv, rfloordiv | 整除(//) |
mul, rmul | 乘法(*) |
pow, rpow | 幂次方(**) |
1.2.1 Series填充值算数方法
# 使用自动的对齐运算
print(s1,'\n')
print(s2,'\n')
print(s1+s2)
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
dtype: int64
0 20
1 21
2 22
3 23
4 24
dtype: int64
0 30.0
1 32.0
2 34.0
3 36.0
4 38.0
5 NaN
6 NaN
7 NaN
8 NaN
9 NaN
dtype: float64
# 使用add方法,设置 fill_value 值,会把series双方对象对齐后的NAN值设置为默认值,参与后续运算
# add方法不修改原series对象
print(s1.add(s2,fill_value=0),'\n')
print(s1)
0 30.0
1 32.0
2 34.0
3 36.0
4 38.0
5 15.0
6 16.0
7 17.0
8 18.0
9 19.0
dtype: float64
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
dtype: int64
print(df1,'\n')
print(df2,'\n')
print(df1+df2)
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 9 10 11
A B D
a 0 1 2
d 3 4 5
f 6 7 8
A B C D
a 0.0 2.0 NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN
d 12.0 14.0 NaN NaN
f NaN NaN NaN NaN
print(df1.add(df2,fill_value = 0))
A B C D
a 0.0 2.0 2.0 2.0
b 3.0 4.0 5.0 NaN
c 6.0 7.0 8.0 NaN
d 12.0 14.0 11.0 5.0
f 6.0 7.0 NaN 8.0
# 当DataFrame对象作为除数的时也可使用rdiv方法
print(1/df1)
A B C
a inf 1.000000 0.500000
b 0.333333 0.250000 0.200000
c 0.166667 0.142857 0.125000
d 0.111111 0.100000 0.090909
# 1/df1 等效于
print(df1.rdiv(1))
A B C
a inf 1.000000 0.500000
b 0.333333 0.250000 0.200000
c 0.166667 0.142857 0.125000
d 0.111111 0.100000 0.090909
1.3 DataFrame与Series混合运算
print(df1,'\n')
# 获取df的第一行的数据
dff1 = df1.iloc[0]
print(dff1,'\n')
# 类似于numpy中的广播机制(匹配行,纵向扩展)
print(df1 - dff1)
# 等价于 print(df1.sub(dff1))
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 9 10 11
A 0
B 1
C 2
Name: a, dtype: int32
A B C
a 0 0 0
b 3 3 3
c 6 6 6
d 9 9 9
print(df1,'\n')
dff2 = df1['A']
print(dff2,'\n')
# 类似于numpy中的广播机制(匹配列,横向扩展)
print(df1.sub(dff2,axis=0))
A B C
a 0 1 2
b 3 4 5
c 6 7 8
d 9 10 11
a 0
b 3
c 6
d 9
Name: A, dtype: int32
A B C
a 0 1 2
b 0 1 2
c 0 1 2
d 0 1 2
二、Pandas的函数应用
2.1 apply 和 applymap
df = pd.DataFrame(np.random.randn(5,4))
print(df,'\n')
0 1 2 3
0 2.031062 0.245420 -0.327614 -1.658527
1 0.099675 1.501878 -0.111316 1.145064
2 0.196965 -1.150081 -2.451549 0.704854
3 0.200604 -0.833344 0.898835 0.421002
4 2.026293 -0.009396 -0.014084 0.352606
# 通过apply将函数应用到列或者行(针对的是Series数据)
f = lambda x:x.max()
# 注意轴的方向,默认axis=0 指列
print(df.apply(f),'\n')
print(df.apply(f,axis=1),'\n')
0 2.031062
1 1.501878
2 0.898835
3 1.145064
dtype: float64
0 2.031062
1 1.501878
2 0.704854
3 0.898835
4 2.026293
dtype: float64
# 通过applymap将函数应用到每个数据
f2 = lambda x: '%.2f' % x
print(df.applymap(f2),'\n')
0 1 2 3
0 2.03 0.25 -0.33 -1.66
1 0.10 1.50 -0.11 1.15
2 0.20 -1.15 -2.45 0.70
3 0.20 -0.83 0.90 0.42
4 2.03 -0.01 -0.01 0.35
- 注意:对于Series只有apply方法,其作用类似于DataFrame中的applymap,会对每个元素值进行操作
2.2 排序
2.2.1 索引排序
s1 = pd.Series(np.arange(4),index=list('dbca'))
print(s1,'\n')
d 0
b 1
c 2
a 3
dtype: int32
# 默认按照index的升序排序
print(s1.sort_index(),'\n')
print(s1)
a 3
b 1
c 2
d 0
dtype: int32
d 0
b 1
c 2
a 3
dtype: int32
# 按照index的降序排序
print(s1.sort_index(ascending=False),'\n')
print(s1)
d 0
c 2
b 1
a 3
dtype: int32
d 0
b 1
c 2
a 3
dtype: int32
pd1 = pd.DataFrame(np.arange(12).reshape((4,3)),index=list('bdca'),columns=list('BCA'))
print(pd1,'\n')
# 按照行排序
print(pd1.sort_index(),'\n')
# 按照列排序
print(pd1.sort_index(axis=1),'\n')
B C A
b 0 1 2
d 3 4 5
c 6 7 8
a 9 10 11
B C A
a 9 10 11
b 0 1 2
c 6 7 8
d 3 4 5
A B C
b 2 0 1
d 5 3 4
c 8 6 7
a 11 9 10
2.2.2 按值排序
# Series按值排序
s1['a'] = np.NAN
print(s1,'\n')
d 0.0
b 1.0
c 2.0
a NaN
dtype: float64
# 根据值的大小进行额排序,当有缺失值,会默认排在最后
print(s1.sort_values(),'\n')
print(s1.sort_values(ascending=False))
d 0.0
b 1.0
c 2.0
a NaN
dtype: float64
c 2.0
b 1.0
d 0.0
a NaN
dtype: float64
# DataFrame按值排序
print(pd1,'\n')
# 按某列的值整体排序
print(pd1.sort_values(by='A',axis=0,ascending=False),'\n')
# 按某些列的值整体排序
print(pd1.sort_values(by=list('AB'),axis=0,ascending=False),'\n')
# 按某行的值整体排序
print(pd1.sort_values(by='a',axis=1,ascending=False),'\n')
# 按某些行的值整体排序
print(pd1.sort_values(by=list('ab'),axis=1,ascending=False))
B C A
b 0 1 2
d 3 4 5
c 6 7 8
a 9 10 11
B C A
a 9 10 11
c 6 7 8
d 3 4 5
b 0 1 2
B C A
a 9 10 11
c 6 7 8
d 3 4 5
b 0 1 2
A C B
b 2 1 0
d 5 4 3
c 8 7 6
a 11 10 9
A C B
b 2 1 0
d 5 4 3
c 8 7 6
a 11 10 9
2.3 唯一值,值计数以及成员属性
s1 = pd.Series([2,6,8,9,8,3,6],index=['a','a','c','c','c','c','c'])
print(s1,'\n')
a 2
a 6
c 8
c 9
c 8
c 3
c 6
dtype: int64
2.3.1 unique方法
# unique方法对Series中values去重,该方法返回一个Numpy.ndarray对象
ss1 = s1.unique()
print(ss1,'\n')
print(type(ss1),'\n')
[2 6 8 9 3]
<class 'numpy.ndarray'>
# 可以判断index是否无重复
print(s1.index.is_unique)
False
s1 = pd.Series([2,6,8,9,8,3,6])
print(s1,'\n')
0 2
1 6
2 8
3 9
4 8
5 3
6 6
dtype: int64
2.3.2 value_counts方法
# value_counts计算value值出现的次数
# 返回一个series,得到各value值出现的次数
print(s1.value_counts())
6 2
8 2
2 1
9 1
3 1
dtype: int64
2.3.3 isin方法
# isin 判断值是否存在,返回的是布尔类型的Series对象
print(s1.isin([8,2]))
0 True
1 False
2 True
3 False
4 True
5 False
6 False
dtype: bool
# DataFrame使用isin方法
data = pd.DataFrame({'a':[3,7,9,0],'b':[1,-1,4,8],'c':[0,6,-3,2]})
print(data,'\n')
a b c
0 3 1 0
1 7 -1 6
2 9 4 -3
3 0 8 2
# isin 判断值是否存在,返回的是布尔类型的DataFrame对象
print(data.isin([0,1]))
a b c
0 False True True
1 False False False
2 False False False
3 True False False
2.4 处理缺失数据
df3 = pd.DataFrame([np.random.randn(3),[1.,2.,np.nan],
[np.nan,4.,np.nan],[1.,2.,3.]])
print(df3)
0 1 2
0 -0.305345 -1.013674 -0.330139
1 1.000000 2.000000 NaN
2 NaN 4.000000 NaN
3 1.000000 2.000000 3.000000
2.4.1 isnull()判断是否为NaN值
# 1.判断是否存在缺失值 isnull()
print(df3.isnull(),'\n')
0 1 2
0 False False False
1 False False True
2 True False True
3 False False False
2.4.2 dropna()丢弃NaN值
# 2. 丢弃缺失数据 dropna()
print(df3.dropna(),'\n') # 默认会丢弃缺失的行数据
print(df3.dropna(axis=1),'\n') # 丢弃缺失的列数据
0 1 2
0 -0.305345 -1.013674 -0.330139
3 1.000000 2.000000 3.000000
1
0 -1.013674
1 2.000000
2 4.000000
3 2.000000
2.4.3 fillna()填充缺失数据
# 3. 填充缺失数据
print(df3,'\n')
print(df3.fillna(-1))
0 1 2
0 -0.305345 -1.013674 -0.330139
1 1.000000 2.000000 NaN
2 NaN 4.000000 NaN
3 1.000000 2.000000 3.000000
0 1 2
0 -0.305345 -1.013674 -0.330139
1 1.000000 2.000000 -1.000000
2 -1.000000 4.000000 -1.000000
3 1.000000 2.000000 3.000000
三、层级索引
3.1 创建层级索引
s1 = pd.Series(np.random.randn(12),index=[['a','a','a','b','b','b','c','c','c','d','d','d'],[0,1,2,0,1,2,0,1,2,0,1,2]])
print(s1,'\n')
a 0 0.639695
1 1.231051
2 -1.591987
b 0 -1.131264
1 -0.541793
2 -1.048820
c 0 1.456716
1 0.217091
2 0.904596
d 0 -0.194636
1 -1.345946
2 -1.435070
dtype: float64
print(type(s1.index),'\n')
print(s1.index)
<class 'pandas.core.indexes.multi.MultiIndex'>
MultiIndex([('a', 0),
('a', 1),
('a', 2),
('b', 0),
('b', 1),
('b', 2),
('c', 0),
('c', 1),
('c', 2),
('d', 0),
('d', 1),
('d', 2)],
)
3.2 使用层级索引选取元素
3.2.1 外层选取
# 1. 外层选取
print(s1['b'])
0 -1.131264
1 -0.541793
2 -1.048820
dtype: float64
3.2.2 内层选取
# 2. 内层选取
# 选取所有外层中指定内层数据的组合
print(s1[:,2],'\n')
# 选取指定数据
print(s1['a',2])
a -1.591987
b -1.048820
c 0.904596
d -1.435070
dtype: float64
-1.5919871141609765
3.2.3 交换内外层索引的顺序
# swaplevel()交换内外层索引
print(s1.swaplevel(),'\n')
0 a 0.639695
1 a 1.231051
2 a -1.591987
0 b -1.131264
1 b -0.541793
2 b -1.048820
0 c 1.456716
1 c 0.217091
2 c 0.904596
0 d -0.194636
1 d -1.345946
2 d -1.435070
dtype: float64
四、Pandas统计计算和描述
arr1 = np.random.rand(4,3)
pd1 = pd.DataFrame(arr1,columns=list('ABC'),index=list('abcd'))
f = lambda x: '%.2f' % x
pd2 = pd1.applymap(f).astype(float)
print(pd2)
A B C
a 0.42 0.52 0.89
b 0.53 0.99 0.09
c 0.40 0.37 0.04
d 0.31 0.13 0.81
常用的统计计算
方法 | 说明 |
---|---|
count | 非NA值的数量 |
describe | 针对Series或各DataFrame列计算汇总统计 |
min、max | 计算最小值和最大值 |
argmin、argmax | 计算能够获取到最小值和最大值的索引位置(整数) |
idxmin、idxmax | 计算能够获取到最小值和最大值的索引位置 |
quantile | 计算样本的分位数(0到1) |
sum | 值的总和 |
mean | 值的平均数 |
median | 值的算术中位数(50%分位数) |
mad | 根据平均值计算平均绝对离差 |
var | 样本的方差 |
std | 样本的标准差 |
skew | 样本的偏度(三阶矩) |
surt | 样本的峰度(四阶矩) |
cumsum | 样本值的累计和 |
cummin、cummax | 样本的累计最大值和累计最小值 |
cumprod | 样本值的累计积 |
diff | 计算一阶差分(对时间序列很有用) |
pct_change | 计算百分数变化 |
- 注:使用聚合函数(如:sum,mean,max,min…)
axis=0 按列统计,axis=1按行统计
skipna 排除缺失值,默认为True
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,'\n')
# 默认按列求和
print(df.sum(),'\n')
print(df.sum(skipna=False),'\n')
one 9.25
two -5.80
dtype: float64
one NaN
two NaN
dtype: float64
# 默认按行求和
print(df.sum(axis=1),'\n')
print(df.sum(axis=1,skipna=False),'\n')
a 1.40
b 2.60
c 0.00
d -0.55
dtype: float64
a NaN
b 2.60
c NaN
d -0.55
dtype: float64
# 返回列中最大值的索引
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
# 显示汇总的统计信息
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