1.数据信息
pandas载入一个数据集后,可以对数据表做一些初步的验证,比如行名、列名是否一致,数据量是否有缺失,各列的数据类型等,接下来这些操作不仅对DataFrame适用,也可以用在Series上。
查看样本
加载完的数据可能由于量太大,我们需要查看验证部分样本数据,pandas提供了3种常用的样式查看方法:
df.head() #返回前N行的数据,默认前5行
df.tail() #返回最后N行的数据,默认最后5行
df.sample() #随机返回一样数据,也可以指定条数df.列标签可以返回数据表中索引列+指定的列
查看DataFrame基本信息
执行df.shape会返回一个元组,该元组的第一个元素代表行数,第二个元素代表列数(不包含行标签(索引)与列标签)
如果对Series使用.shape,那么这个元组中就只有一个值和一个英文逗号,类似(1,)
df.info可以返回所有数据的类型、索引情况、行列数、各字段数据类型、内存占用等,不适用于Series。
df.dtypes可以返回每一列的数据类型以及DataFrame整体的类型,Series对应的操作是dtype
df.axes会读取索引列与表头,并将这两组数据以及对应的数据类型组成一个列表返回,格式如下:
df.axes
”’
[RangeIndex(start=0, stop=100, step=1),
Index([‘name’, ‘team’, ‘Q1’, ‘Q2’, ‘Q3’, ‘Q4′], dtype=’object’)]
”’
Series的axes会返回列索引内容,格式如下:
s.axes
# [RangeIndex(start=0, stop=100, step=1)]
DataFrame其他信息获取方法:
# 索引对象
df.index
# RangeIndex(start=0, stop=100, step=1)
# 列索引,Series不支持
df.columns
# Index([‘name’, ‘team’, ‘Q1’, ‘Q2’, ‘Q3’, ‘Q4′], dtype=’object’)
df.values # array(<所有值的列表矩阵>)
df.ndim # 2 维度数
df.size # 600行×列的总数,就是总共有多少数据
# 是否为空,注意,有空值不认为是空
df.empty # False
# Series的索引,DataFrame的列名
df.keys()
Series独有的方法:
s.name # ‘Q1’
s.array # 值组成的数组
s.dtype # 类型,dtype(‘int64’)
s.hasnans # False
s.name可获取索引的名称,需要区分的是上例数据中df.name也能正常执行,它其实是df调用数据字段的方法,因为正好有名为name的列,如果没有就会报错,DataFrame是没有此属性的。
2.统计计算
pandas可以对Series与DataFrame进行快速的描述性统计,如求和、平均数、最大值、方差等,这些是最基础也最实用的统计方法。
对于DataFrame,这些统计方法会按列进行计算,然后返回一个以列标签为索引,亿计算值为值的Series。
描述统计
df.describe()可以返回一个有多行的所有数字列的统计表DataFrame,每一行对应一个统计指标,有总数、平均数、标准差、最小值、四分位数、最大值等。
也就是计算原DataFrame每一列的总数、平均数、标准差、最小值、四分位数、最大值,然后将结果返回一个新的DataFrame。
如果没有数字,则会输出与字符串相关的统计数据,如数量、不重复值数、最大值(字符按首字母顺序)等。
df.describe()也支持对时间数据的描述性统计:
(pd.Series(pd.date_range('2000-01-01', '2000-05-01'))
.describe(datetime_is_numeric=True)
)
'''
count 122
mean 2000-03-01 12:00:00
min 2000-01-01 00:00:00
25% 2000-01-31 06:00:00
50% 2000-03-01 12:00:00
75% 2000-03-31 18:00:00
max 2000-05-01 00:00:00
dtype: object
'''
还可以自己指定分位数(一般情况下,默认值包含中位数),指定和排除数据类型:
df.describe(percentiles=[.05, .25, .75, .95])
df.describe(include=[np.object, np.number]) # 指定类型
df.describe(exclude =[np.object]) # 排除类型
数学统计
在未来版本可能会报错
pandas支持常用的数学统计方法,如平均数mean()、中位数、众数、方差等,还可以结合NumPy使用更加丰富的统计功能。
对DataFrame使用统计函数后,会返回一个Series,原DataFrame的列标签会变成索引,每个索引对应它的计算结果,会忽略掉DataFrame非数值类型的列,如果DataFrame没有任何数字类型列,则会报错
对Series使用统计函数,只会返回一个数字,也就是计算结果。
默认情况下,统计函数是按列统计的,如果要按行来统计,可以传入axis参数,列传index或0,行传columns或1
df.mean(axis='columns')
df.mean(axis=1) # 效果同上
df.mean(1) # 效果同上
'''
0 49.50
1 41.75
2 54.75
3 84.50
4 65.25
...
95 67.00
96 31.25
97 53.00
98 58.50
99 44.75
Length: 100, dtype: float64
'''
上述代码值对数字类型的列起作用,会忽略文本等其他类型,此外可以发现,索引依然是从0开始的序列索引,让人无法分辨,所以需要先用set_index()函数指定某一列为索引,然后再计算。
pandas中统计函数如下:
df.mean() # 返回所有列的均值
df.mean(1) # 返回所有行的均值,下同
df.corr() # 返回列与列之间的相关系数
df.count() # 返回每一列中的非空值的个数
df.max() # 返回每一列的最大值
df.min() # 返回每一列的最小值
df.abs() # 绝对值
df.median() # 返回每一列的中位数
df.std() # 返回每一列的标准差,贝塞尔校正的样本标准偏差
df.var() # 无偏方差
df.sem() # 平均值的标准误差
df.mode() # 众数
df.prod() # 连乘
df.mad() # 平均绝对偏差
df.cumprod() # 累积连乘,累乘
df.cumsum(axis=0) # 累积连加,累加
df.nunique() # 去重数量,不同值的量
df.idxmax() # 每列最大值的索引名
df.idxmin() # 每列最小值的索引名
df.cummax() # 累积最大值
df.cummin() # 累积最小值
df.skew() # 样本偏度(第三阶)
df.kurt() # 样本峰度(第四阶)
df.quantile() # 样本分位数(不同 % 的值)
pandas还提供了一些特殊的用法
# 很多支持指定行列(默认是axis=0列)等参数
df.mean(1) # 按行计算
# 很多函数均支持
df.sum(0, skipna=False) # 不除缺失数据
# 很多函数均支持
df.sum(level='blooded') # 索引级别
df.sum(level=0)
# 执行加法操作所需的最小有效值数
df.sum(min_count=1)
非统计计算
除了简单的数学统计外,我们往往还需要对数据做非统计性计算,如去重、格式化等。方法有下面这些:
df.all() # 该列数值是否全都可以表示为True
df.any() #该列数值是否至少有一个可以表示为True
# 四舍五入
df.round(2) # 指定字段指定保留小数位,如有
df.round({‘Q1’: 2, ‘Q2’: 0})
df.round(-1) # 保留10位
# 每个列的去重值的数量
df.nunique() #不算重复的,每一列有多少个值
s.nunique() # 本列的去重值
# 真假检测
df.isna() # 值的真假值替换
df.notna() # 与上相反
以下可以传给一个值或者另一个DataFrame,对数据进行广播方式计算,返回计算后的DataFrame:
df + 1 # 等运算
df.add() # 加
df.sub() # 减
df.mul() # 乘
df.div() # 除
df.mod() # 模,除后的余数
df.pow() # 指数幂
df.dot(df2) # 矩阵运算
以下是Series专有的一些函数:
# 不重复的值及数量
s.value_counts()
s.value_counts(normalize=True) # 重复值的频率
s.value_counts(sort=False) # 不按频率排序
s.unique() # 去重的值 array
s.is_unique # 是否有重复
# 最大最小值
s.nlargest() # 最大的前5个
s.nlargest(15) # 最大的前15个
s.nsmallest() # 最小的前5个
s.nsmallest(15) # 最小的前15个
s.pct_change() # 计算与前一行的变化百分比
s.pct_change(periods=2) # 前两行
s1.cov(s2) # 两个序列的协方差
3.位置计算
diff()和shift()经常被用来计算数据的增量变化,rank()用来生成数据的整体排名。
位置差值diff()
df.diff()可以做位移差操作,经常用来计算一个序列数据中上一个数据和下一个数据之间的差值,如增量研究。
每一行默认返回这一行减上一行的计算结果,可以填写参数来指定计算的位置,1就是这一行减上一行,-1就是这一行减下一行,以此类推。
默认被减的数列下移一位,原数据在同位置上对移动后的数据相减,得到一个新的序列,第一位由于被减数下移,没有数据,所以结果为NaN。
可以传入一个数值来规定移动多少位,负数代表移动方向相反。
非数字的Series类型使用此方法会报错,DataFrame会对所有数字列移动计算,同时不允许有非数字类型。
DataFrame可以新增一列来存放计算结果:数据表[‘新列’]=数据表.列标签.diff())
DataFrame除了可以纵向计算,还可以横向计算,但需要选择需要计算的数据范围,比如:
df.loc[:5,’列标签1′:’列标签2′].diff(axis=1) #loc选择数据范围,:5表示前5行,然后另一个参数指定从哪个列标签到哪个列标签,最后在.diff()中加入axis=1参数表示横向计算,会返回一个DataFrame。
位置移动
shift()可以对数据位移但不进行任何计算,支持上下左右移动,移动后目标位置的类型无法接收的为NaN。
不填参数默认整体下移一行,最上一行有空缺,字符串类型会被填充None,数值类型的列会被填充NaN.
可以指定某一列上下移动,返回一个Series:df.列标签.shift(-1)”
如果设置axis=1,那么就会横向移动,整体右移一位
# 整体下移一行,最顶的一行为NaN
df.shift()
df.shift(3) # 移三行
# 整体上移一行,最底的一行为NaN
df.Q1.head().shift(-1)
# 向右移动一位
df.shift(axis=1)
df.shift(3, axis=1) # 移三位
# 向左移动一位
df.shift(-1, axis=1)
# 实现了df.Q1.diff()
df.Q1 - df.Q1.shift()
位置序号
rank()可以生成数据的排序值替换原来的数据值,它支持对所有类型数据进行排序,如英文会按字母排序。使用rank()的典型例子有学生的成绩表,给出排名。
如果这一列的内容是字符串,那么按照英文字母,最前面的英文字母排第一,如果是数字类型,数值最小的排第一
如果为rank()方法加入axis=1的参数,可以横向,也就是在在一行中排序,会忽略掉非数字形式的列,在未来这一功能可能会被移除
如果为rank()方法加入pct=True参数,可以将序数转换成从0到1的小数,数值最小,或者首字母排名最靠前,在排序结果中分配的小数的值也就越小
method参数可以设置,在排序过程中出现相同值的处理方法,可取的值有下面几个:
average:序号的平均值,如并列第1名,则按二次元计算(1+2)/2,都显示1.5,下个数据的值为3。
min:最小的序数,如并列第1名,则都显示1,下个数据为3。
max:最大的序数,如并列第1名,则都显示1,下个数据为2。
first:如并列第1名,则都显示1,下个数据为2。dense:按照索引的先后显示。
如果遇到空值,可以传入na_option=’bottom’,把空值放在最后,值为top放在最前。
4.数据选择
通过loc与iloc方法,可以模拟Excel对数据的选择查询操作,可以选择一列、一行,甚至按条件筛选数据。
pandas中常用的数据选择操作:
操作 | 语法 |
选择列 | df[col] |
按索引选择行 | df.loc[label] |
按数字索引选择行 | df.iloc[label] |
使用切片选择行 | df[起始值:最终值] |
用表达式筛选行 | df[bool_vec] |
选择列
选择DataFrame的列可以有以下几种格式:
df.列标签 #返回Series
需要注意的是,这样的方法只有在列标签可以作为一个合法的Python变量才能使用,如果列标签以数字开头,或者有空格,则会报错,如果想用这种方法,需要先将特定的列标签进行处理,比如将空格替换成下划线,或者增加前缀
df[‘列标签’] #返回Series 只能选择一列,选择多列需要2个中括号
df[[‘列标签1′,’列标签2’]] #选择多列,注意有2个中括号,返回的类型为DataFrame
切片方式选择行
可以像列表那样利用切片功能选择部分行的数据,但是不支持仅索引一条数据:
需要注意的是,切片时,索引值从0开始,并且不会保留最后一个额索引的值,比如[0:2],智慧保留索引值为0、1的元素,不包含索引值2的元素
df[:2] # 前两行数据
df[4:10] #索引值4到索引值9的行
df[:] # 所有数据,一般不这么用
df[:10:2] # 按步长取
s[::-1] # 反转顺序
df[2] # 报错!
轴标签loc
可以根据索引或列的名称来选择
df.loc的格式是df.loc[<行表达式>,<列表达式>],如列表达式部分不传,则返回所有列,
Series仅支持行表达式进行索引的部分。
loc操作通过索引和列的条件筛选出数据,如果仅返回一条数据,则类型为Series。
返回结果如果是Series,原DataFrame数据表的列标签会变成索引,原数据表列标签下的每个值,会变成每一行索引对应的值,类似于进行了行与列互换的操作:
df.loc[0] #选择索引值为0的行
可以先将一列指定为索引,然后根据这新的索引,也就是原来列标签的内容来选择行
df.set_index(‘列标签’).loc[‘列标签下的内容’]
如果选择多行,可以在loc参数中加入英文冒号,表示从哪一行到哪一行
df.loc[0:10] #从索引值为0的行到索引值为10的行
仅在索引值为从0开始的自然数序列有用,如果自己设置了其它索引,那么df.loc参数就不是数字,而是加了引号的文本:df.loc[‘起始行’:’结束行’]
df.loc[:]表示选择所有行
如果loc后面跟着两个中括号,也就是df.loc[[]],也可以选择多行,
比如df.loc[[0,3,1]]就是输出索引值分别为0,3,1的行,行的排序也会跟loc参数中一致
附带列筛选,必须先有行筛选。列部分的表达式可以是一个由希望筛选的表明组成的列表,也可以是一个用冒号隔开的切片形式,来表示从左到右全部包含,左侧和右侧可以分别省略,表示本侧所有列。
df.loc[0:3,[‘列标签1′,’列标签2’]] #选择索引值从0到3的行,然后只取列标签1和列标签2的列
df.loc[ : , ‘列标签’ : ] #表示选择所有行,然后筛选从列标签1开始的往后所有的列
总之,选择列标签时,如果按照切片的方式,列标签的表达式为英文冒号,如果按照自己指定的行,则是中括号[]里填写自己指定的列标签。
按数字索引.iloc
与loc[]可以使用索引和列的名称不同,利用iloc[<行表达式>,<列表达式>]格式可以使用数字索引(行和列的0~n索引)进行数据筛选,意味着iloc[]的两个表达式仅支持数字切片形式,其他方面都是相同的。
注意切片操作时,-1表示倒数第二
df.iloc[:3] # 前三行
s.iloc[:3] # 序列中的前三个
df.iloc[:] # 所有数据
df.iloc[2:20:3] # 步长为3
df.iloc[:3, [0,1]] # 前两列
df.iloc[:3, :] # 所有列
df.iloc[:3, :-2] # 从右往左第三列以左的所有列
以上方法可以在行和列的表达式中混用,.iloc中的表达式部分支持条件表达式,可以按条件数据查询。
取具体指.at/.iat
如果需要取数据中一个具体的值,就像取平面直角坐标系中的一个点一样,可以使用.at[]来实现。
.at类似于loc,仅取一个具体的值,结构为df.at[<索引>,<列名>]。
如果是Series,可以直接通过索引取到对应的值
格式:
df.at[‘索引’,’列标签’] #如果DataFrame的索引不是数字序列,而是文本,需要加入引号
也可以先锁定列,再锁定值:df.列标签.[索引]
# 注:索引是字符,需要加引号
df.at[4, 'Q1'] # 65
df.set_index('name').at['Ben', 'Q1'] # 21 索引是name
df.at[0, 'name'] # 'Liver'
df.loc[0].at['name'] # 'Liver'
# 指定列的值对应其他列的值
df.set_index('name').at['Eorge', 'team'] # 'C'
df.set_index('name').team.at['Eorge'] # 'C'
# 指定列的对应索引的值
df.team.at[3] # 'C'
iat和iloc一样,仅支持数字索引
df.iat[行索引值, 列索引值] #通过行索引与列索引取值,这里的索引与DataFrame的index无关
df.loc[index].iat[1] # 先根据DataFrame的索引index选择行,然后根据普通的数字索引选择列,索引值0表示第一列
数据获取.get
.get可以做类似字典的操作,如果没有值,则返回默认值。
使用方法是df.get(‘列标签’,’默认返回值’),如果找到列标签,返回列标签的 那一列,,如果没找到指定的列标签,返回设定好的返回值,不填写则默认返回None。
如果是DataFrame,key需要传入列名,返回的是此列的Series,
如果是Series,需要传入索引,返回的是一个定值。
数据截取.truncate
df.druncate()可以对DataFrame和Series进行截取,可以将索引传入before和after参数,将这个区间以外的数据剔除。
意思就是,只取第几行到到几行的内容,给定2个行的数字索引值即可。
测试的过程中,发现值对默认的从0开始的数字序列索引有效,如果将索引改成其他列,则会报错。
df.truncate(2,5) #从索引值为2的行到索引值为5的行
索引选择器
pd.IndexSlice是一个专门的索引选择器,它的使用方法类似df.loc[]切片中的方法,常用在多层索引中,以及需要指定应用范围(subset参数)的函数中,特别是在链式方法中。
df.loc[pd.IndexSlice[:, ['Q1', 'Q2']]]
# 变量化使用
idx = pd.IndexSlice
df.loc[idx[:, ['Q1', 'Q2']]]
df.loc[idx[:, 'Q1':'Q4'], :] # 多索引
还可以按条件查询创建复杂的选择器,一下是几个案例:
# 创建复杂条件选择器
selected = df.loc[(df.列标签1=='A') & (df.列标签2>90)]
idxs = pd.IndexSlice[selected.index, '列标签']
# 应用选择器
df.loc[idxs]
# 选择这部分区域加样式
df.style.applymap(style_fun, subset=idxs)