pandas之初探index对象
一 前言
经过前面2篇的Series和DataFrame基本学习,本篇再次学完index,那么pandas基本对象就已经学完了,想要更深入的研究学习,读者还是需要参照官网;
公众号:知识追寻者
知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)
二 index 的特性
index 对象的索引具有可重复性;index对象具有不可变性;如下所示索引 中重复了2次z ,能够正常运行;
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
index = ['z', 's', 'z', 'x', 'z']
data = ['t', 'o', 'y', 'o', 'u']
ser = pd.Series(data = data, index = index)
print(ser)
输出
z t
s o
z y
x o
z u
dtype: object
选取重复的索引返回的将不再是单一值,而是个Series对象;
index = ['z', 's', 'z', 'x', 'z']
data = ['t', 'o', 'y', 'o', 'u']
ser = pd.Series(data = data, index = index)
print(ser['z'])
输出
z t
z y
z u
dtype: object
三 index 常用方法
3.1 reindex
使用reindex有个注意点就是原来的索引必须出现在新索引中,顺序可不一致,也可引进新索引;reindex的作用就是对原来的索引进行重新排序,如果索引长度大于原有数据长度会使用NaN补充;
index = ['l', 'o', 'v', 'e', 'r']
data = ['i', 's', 'y', 'o', 'u']
ser = pd.Series(data = data, index = index)
reser = ser.reindex(['r', 'e', 'l', 'o', 'v', 'e'])
print(reser)
输出
r u
e o
l i
o s
v y
l i
dtype: object
3.2 填充
由于重新索引之后难免会引入新的索引,此时就是会使用NaN代替,如果想要数据表现得蜂蜜一些,则需要对新索引得数据进行填充;注意向前填充和向后填充都是单一的递增或者递减方式进行填充,如果顺序有问题会出现NaN.
向前填充
,o,v等字母会大于a,会填充a的值,z的值有重复会填充原来z的值;读者如果将a换成w有惊喜哟!就会出现比w小的索引的值都是NaN
index = ['a', 'z']
data = ['i', 's']
ser = pd.Series(data = data, index = index)
reser = ser.reindex(['o', 'z', 'v', 'o', 'k', 'y'],method='ffill' )
print(reser)
输出
o i
z s
v i
o i
k i
y i
dtype: object
向后填充
顺序比s小的字母才会填充s的值,顺序比s大的值使用NaN代替;
index = ['a', 's']
data = ['i', 's']
ser = pd.Series(data = data, index = index)
reser = ser.reindex(['l', 'z', 'v', 'o', 'k', 'y'],method='bfill' )
print(reser)
输出
l s
z NaN
v NaN
o s
k s
y NaN
dtype: object
3.3 删除索引
使用 drop()
方法就可以删除 索引,也就是删除数据集得一行;如果想删除多个索引标签就需要传参为数组比如['user2','user3']
index = ['user1', 'user2', 'user3']
data = ['zszxz', 'caler', 'rose']
ser = pd.Series(index=index, data=data)
print(ser.drop('user3'))
输出
user1 zszxz
user2 caler
dtype: object
如果是 DataFrame 需要直接删除索引也是和Series一样得操作,如下示例中(frame.drop(['craler','rose']
))就会删除 craler 和 rose 得两行得索引数据;
dic = {
'user1':{'zszxz':0,'craler':1,'rose':2},
'user2':{'zszxz':3,'craler':4,'rose':5},
'user3':{'zszxz':6,'craler':7,'rose':8}
}
frame = pd.DataFrame(dic)
print(frame.drop(['craler','rose']))
输出
user1 user2 user3
zszxz 0 3 6
如果想要删除列,则需要指定轴,axis = 0 表示 行, axis = 1 表示列 ;如下示例中表示删除列 user1, 和 user2;
dic = {
'user1':{'zszxz':0,'craler':1,'rose':2},
'user2':{'zszxz':3,'craler':4,'rose':5},
'user3':{'zszxz':6,'craler':7,'rose':8}
}
frame = pd.DataFrame(dic)
print(frame.drop(['user1','user2'],axis=1))
输出
user3
zszxz 6
craler 7
rose 8
四 简单运算
两个Series 相加,具有相同的索引会按照对应的索引位置相加,否则使用NaN填充;
index = ['user1', 'user2', 'user3']
data = [6, 8, 10]
ser1 = pd.Series(data = data, index = index)
index = ['user1', 'user2', 'user3', 'user4']
data = [4, 2, 10, 20]
ser2 = pd.Series(data = data, index = index)
print(ser1 + ser2)
输出
user1 10.0
user2 10.0
user3 20.0
user4 NaN
dtype: float64
使用 DataFrame 进行加法,则需要严格按照行列对齐方式对应的位置元素进行相加;如果有多余的列,则会用NaN填充该列的值
frame1 = pd.DataFrame(
data = np.arange(9).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
frame2 = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame1 + frame2)
输出
user1 user2 user3
zszxz 0 3 6
craler 9 12 15
rose 18 21 24
注 : 减法等与加法是同样的道理;
五 函数运算
通常,DataFrame在运算时还是使用正规的函数进行运算比较好;也是遵守行列对其规则;下面中frame2对应的位置是frame1位置元素的两倍,除了第一个位置;关于更多的函数使用读者可以参照官网
5.1 add()
加法,对应位置相加,多余的使用NaN填充;
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame1 = pd.DataFrame(
data = np.arange(9).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
frame2 = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame1.add(frame2))
输出
user1 user2 user3
zszxz 0 3 6
craler 9 12 15
rose 18 21 24
5.2 sub()
减法
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame1 = pd.DataFrame(
data = np.arange(9).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
frame2 = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame2.sub(frame1))
输出
user1 user2 user3
zszxz 0 1 2
craler 3 4 5
rose 6 7 8
5.3 div()
除法, 0/0 为 NaN
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame1 = pd.DataFrame(
data = np.arange(9).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
frame2 = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame2.div(frame1))
输出
user1 user2 user3
zszxz NaN 2.0 2.0
craler 2.0 2.0 2.0
rose 2.0 2.0 2.0
5.4 mul()
乘法
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame1 = pd.DataFrame(
data = np.arange(9).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
frame2 = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame2.mul(frame1))
输出
user1 user2 user3
zszxz 0 2 8
craler 18 32 50
rose 72 98 128
六Series 与 DataFrame之间的运算
Series 与 DataFrame 之间的运算也跟numpy的数组类似,遵循广播原则;如下示例中默认会执行运算匹配至DataFrame的列;如果Series 的 索引与 DataFrame的列不同,做运算后会产生并集,并且不同索引的位置使用NaN代替;
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
)
print('-----DataFrame------')
print(frame)
ser = pd.Series(data=np.arange(3), index=['user1', 'user2', 'user3'])
print('-----series------')
print(ser)
print('-----相减------')
print(frame - ser)
输出
user1 user2 user3
0 0 2 4
1 6 8 10
2 12 14 16
-----series------
user1 0
user2 1
user3 2
dtype: int32
-----相减------
user1 user2 user3
0 0 1 2
1 6 7 8
2 12 13 14
如果想要匹配运算至DataFrame 的 的行运算则需要指定 axis = 0 或者 axis = ['index']
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
frame = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
)
print('-----DataFrame------')
print(frame)
ser = pd.Series(data=np.arange(3))
print('-----series------')
print(ser)
print('-----相减------')
print(frame.sub(ser, axis = 0))
输出
-----DataFrame------
user1 user2 user3
0 0 2 4
1 6 8 10
2 12 14 16
-----series------
0 0
1 1
2 2
dtype: int32
-----相减------
user1 user2 user3
0 0 2 4
1 5 7 9
2 10 12 14
七 选值
关于切片选值,其实在Series , DataFrame 的文章已经具体阐述过了。比较规范的选取可以使用loc属性;
ser.loc['user1'] 与 ser['user1'] 是同样的道理;
index = ['user1', 'user2', 'user3']
data = [6, 8, 10]
ser = pd.Series(data = data, index = index)
print(ser.loc['user1'])
输出
6
再看看DataFrame , 首先需要锁定索引,其次是列 (frame.loc['zszxz','user2']);索引为zszxz , 列为user2;这样就可以获得该位置的值,如果要赋值 就是 frame.loc['zszxz','user2']=100
;
frame = pd.DataFrame(
data = np.arange(0,18,2).reshape((3,3)),
columns= ['user1', 'user2', 'user3'],
index = ['zszxz','craler', 'rose']
)
print(frame.loc['zszxz','user2'])
输出
2
八 常用函数说明
这边指的常用是指对数据集的的操作,会应用至DataFrame每个元素,具体的输出形式读者可以自行试验;如果读者有更高级的算术需求,可以自定义函数,比如匿名函数等等;在之前的文章中提到过的函数将不再赘述;
函数名称 | 函数作用 | 示例 |
---|---|---|
numpy.sqrt() | 对每个元数取平方根 | numpy.sqrt(frame) |
DataFrame.sum() | 求每个列的和 | frame.sum() |
DataFrame.mean() | 求每个列的均值 | frame.mean() |
DataFrame.count() | 求每列的数量 | frame.count() |
DataFrame.descripe() | 计算多个统计量 | frame.descripe |
DataFrame.sort_index() | 对索引按照字母顺序进行重新排序;ascending指定布尔值可以进行升序或者降序; | frame.sort_index(axis=1) |
DataFrame.sort_values() | 对值进行排序,NaN默认最大,by参数可指定哪些列进行排序 | frame.sort_values() |
Series.order() | 对index进行排序 | ser.order() |
DataFrame.rank() | 默认是平均排名,也可以用参数 method = 'first'指定为原始数据排名,还有更多选项和入参参照官网 | frame.rank() |
DataFrame.corr() | 计算相关性 | frame.corr() |
DataFrame.cov() | 计算协方差 | frame.cov() |
DataFrame.corrwith() | 计算2个数据集之间的相关性; | frame1.corrwith(frame2) |
DataFrame.fillna() | 替换NaN为同一个元素 | frame.fillna(0) |