介绍
基于Numpy构建,为数据分析而存在
一位数组series+二维数组dataframe
可直接读取数据并做处理
兼容各种数据库
支持各种分析算法
series
数据结构
Series 是带有标签的一维数组,可以保存任何数据类型(整数,字符串,浮点数,Python对象等),轴标签统称为索引
s = pd.Series(np.random.rand(5))
s.index
s.values
核心:series相比于ndarray,是一个自带索引index的数组 → 一维数组 + 对应索引
当只看series的值的时候,就是一个ndarray
series和ndarray较相似,索引切片功能差别不大
series和dict相比,series更像一个有顺序的字典(dict本身不存在顺序),其索引原理与字典相似(一个用key,一个用index)
创建方法
创建方法一:由字典创建,字典的key就是index,values就是values
dic = {'a':1 ,'b':2 , 'c':3, '4':4, '5':5}
s = pd.Series(dic)
创建方法二:由数组创建(一维数组)
arr = np.random.randn(5)
s = pd.Series(arr)
创建方法三:由标量创建
s = pd.Series(10, index = range(4))
名称属性:name
位置下标 类似序列
无法用s[-1]这种方式取值
s[0]
标签索引
根据标签查值
s['a']
如果需要选择多个标签的值,用[[]]来表示(相当于[]中包含一个列表)
多标签索引结果是新的数组
切片索引
s2[:-1]
s1[1:4]
下标索引做切片,和list写法一样
布尔型索引
print(s[s > 50])
数据查看
s.head(10)
s.tail()
重新索引reindex
是返回新的数据对象
fill_value参数:填充缺失值的值
Series对齐
series 和 ndarray 之间的主要区别是,Series 上的操作会根据标签自动对齐
index顺序不会影响数值计算,以标签来计算
空值和任何值计算结果扔为空值
删除:.drop
s.drop(['g','j'])
drop 删除元素之后返回副本(inplace=False)
添加
直接通过下标索引/标签index添加值
s1[5] = 100
通过.append方法,直接添加一个数组
s1.append(s2)
.append方法生成一个新的数组,不改变之前的数组
修改
s['a'] = 100
dataframe
数据结构
ataframe是一个表格型的数据结构,“带有标签的二维数组”。
Dataframe带有index(行标签)和columns(列标签)
.columns查看列标签
.index查看行标签
.values查看值,数据类型为ndarray
创建方法
Dataframe 创建方法一:由数组/list组成的字典
Dataframe 创建方法二:由Series组成的字典
ataframe 创建方法三:通过二维数组直接创建
Dataframe 创建方法四:由字典组成的列表
Dataframe 创建方法五:由字典组成的字典
选择行与列
data1 = df['a']
按照列名选择列,只选择一列输出Series,选择多列输出Dataframe
data3 = df.loc['one']
按照index选择行,只选择一行输出Series,选择多行输出Dataframe
核心笔记:df[col]一般用于选择列,[]中写列名
核心笔记:df.loc[label]主要针对index选择行,同时支持指定index,及默认数字index
df.iloc[]
按照整数位置(从轴的0到length-1)选择行
切片索引
df.iloc[1:3]
选择列
data1 = df['a']
按index选择行
data1 = df1.loc['one']
切片法选择行
data3 = df[:1]
按整数位置选择行
布尔型索引
b2 = df['a'] > 50
和Series原理相同
多重索引:比如同时索引行和列
先选择列再选择行 —— 相当于对于一个数据,先筛选字段,再选择数据量
df['a'].loc[['one','three']]
df[df['a'] < 50].iloc[:2]
数据查看、转置
df.head(2)
df.tail()
df.T
添加与修改
df.loc[4] = 20
修该列名称
.columns=['','']
修改行名称
.index=['','']
删除 del / drop()
del语句 - 删除列
del df['a']
drop()删除行,inplace=False → 删除后生成新的数据,不改变原数据
df.drop([1,2])
drop()删除列,需要加上axis = 1,inplace=False → 删除后生成新的数据,不改变原数据
df.drop(['d'], axis = 1)
对齐
DataFrame对象之间的数据自动按照列和索引(行标签)对齐
df1 + df2
按值排序
df1.sort_values(['a'], ascending = True)
升序
索引排序
df1.sort_index()
时间
时间模块
datetime.date:date对象
today = datetime.date.today()
datetime.datetime:datetime对象
now = datetime.datetime.now()
datetime.timedelta:时间差
yestoday = today - datetime.timedelta(1)
时间差主要用作时间的加减法,相当于可被识别的时间“差值”
t2-t1
相减得到时间差 —— timedelta
parser.parse:日期字符串转换
parse('2000-1-1')
parse('5/1/2014')
parse('Jan 31, 1997 10:45 PM')
各种格式可以解析,但无法支持中文
from dateutil.parser import parse
时刻数据
pd.Timestamp()
pd.Timestamp('2017-12-21' )
直接生成pandas的时刻数据 → 时间戳
数据类型为 pandas的Timestamp
时刻数据代表时间点,是pandas的数据类型,是将值与时间点相关联的最基本类型的时间序列数据
pd.to_datetime
pd.to_datetime('2017-12-21')
pd.to_datetime():如果是单个时间数据,转换成pandas的时刻数据,数据类型为Timestamp
多个时间数据,将会转换为pandas的DatetimeIndex
当一组时间序列中夹杂其他格式数据,可用errors参数返回
errors = 'ignore':不可解析时返回原始输入,这里就是直接生成一般数组
t4 = pd.to_datetime(date3, errors = 'coerce')
errors = 'coerce':不可扩展,缺失值返回NaT(Not a Time),结果认为DatetimeIndex
时间戳索引
pd.DatetimeIndex()与TimeSeries时间序列
直接生成时间戳索引,支持str、datetime.datetime
单个时间戳为Timestamp,多个时间戳为DatetimeIndex
日期
pd.date_range() 日期范围:生成日期范围
2种生成方式:①start + end; ②start/end + periods
默认频率:day
直接生成DatetimeIndex
start:开始时间
end:结束时间
periods:偏移量
freq:频率,默认天
freq = 'B'
每工作日
freq = 'H'
每小时
freq = 'T'
每分
freq = 'S'
每秒
freq = 'W-MON'
W-MON:从指定星期几开始算起,每周
星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN
freq = 'Q-DEC')
Q-月:指定月为季度末,每个季度末最后一月的最后一个日历日
A-月:每年指定月份的最后一个日历日
月缩写:JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC
所以Q-月只有三种情况:1-4-7-10,2-5-8-11,3-6-9-12
BM:每月最后一个工作日
BQ-月:指定月为季度末,每个季度末最后一月的最后一个工作日
BA-月:每年指定月份的最后一个工作日
M:每月第一个日历日
Q-月:指定月为季度末,每个季度末最后一月的第一个日历日
A-月:每年指定月份的第一个日历日
BM:每月第一个工作日
BQ-月:指定月为季度末,每个季度末最后一月的第一个工作日
BA-月:每年指定月份的第一个工作日
freq = '7D'
7天
freq = '2h30min'
2小时30分钟
tz:时区
normalize:时间参数值正则化到午夜时间戳
closed:默认为None的情况下,左闭右闭,left则左闭右开,right则左开右闭
pd.bdate_range()默认频率为工作日
pd.date_range()-日期范围:频率(1)
pd.date_range()-日期范围:频率(2)
pd.date_range()-日期范围:复合频率
asfreq:时期频率转换
ts.asfreq('4H',method = 'ffill')
改变频率,这里是D改为4H
method:插值模式,None不插值,ffill用之前值填充,bfill用之后值填充
pd.date_range()-日期范围:超前/滞后数据
pd.Period()创建时期
pd.period_range()创建时期范围
asfreq:频率转换
时间戳与时期之间的转换:pd.to_period()、pd.to_timestamp()
时间序列
索引及切片
索引
ts[0]
ts[:2]
切片
ts['2017/1/5':'2017/1/10']
重复索引的时间序列
index有重复,is_unique检查 → values唯一,index不唯一
通过groupby做分组,重复的值这里用平均值处理
重采样
.resample()
ts.resample('5D'):得到一个重采样构建器,频率改为5天
ts.resample('5D').sum():得到一个新的聚合后的Series,聚合方式为求和
freq:重采样频率 → ts.resample('5D')
.sum():聚合方法
降采样
closed:各时间段哪一端是闭合(即包含)的,默认 左闭右闭
升采样及插值
ts.resample('15T').asfreq()
.asfreq():不做填充,返回Nan
ts.resample('15T').ffill()
.ffill():向上填充
ts.resample('15T').bfill()
.bfill():向下填充
低频转高频,主要是如何插值
时期重采样 - Period
ts.resample('3M').sum()
降采样
ts.resample('15D').ffill()
升采样
将一列时间数据的天数取出来
df['date'] =pd.to_datetime(df['update_time']).dt.day
数值计算和统计基础
基本参数:axis、skipna
np.nan :空值
.mean()计算均值
只统计数字列
df.mean(axis=1)
axis参数:默认为0,以列来计算,axis=1,以行来计算,这里就按照行来汇总了
df.mean(skipna=False)
skipna参数:是否忽略NaN,默认True,如False,有NaN的列统计结果仍未NaN
主要数学计算方法,可用于Series和DataFrame(1)
print(df.count(),'→ count统计非Na值的数量\n')
print(df.min(),'→ min统计最小值\n',df['key2'].max(),'→ max统计最大值\n')
print(df.quantile(q=0.75),'→ quantile统计分位数,参数q确定位置\n')
(df.quantile(q=0.75)
用于标准化数据,去除异常值的函数会用到
print(df.sum(),'→ sum求和\n')
print(df.mean(),'→ mean求平均值\n')
print(df.median(),'→ median求算数中位数,50%分位数\n')
print(df.std(),'\n',df.var(),'→ std,var分别求标准差,方差\n')
print(df.skew(),'→ skew样本的偏度\n')
print(df.kurt(),'→ kurt样本的峰度\n')
主要数学计算方法,可用于Series和DataFrame(2)
cumsum样本的累计和
cumprod样本的累计积
cummax,cummin分别求累计最大值,累计最小值
唯一值:.unique()
把序列中去重
值计数:.value_counts()
pd.value_counts(sc, sort = False)
把序列中每个字符出现的次数做统计
成员资格:.isin()
判断序列中的数据是否与另一个序列中的数据相同
文本数据
通过str访问,且自动排除丢失/ NA值
print(s.str.count('b'))
# 直接通过.str调用字符串方法
# 可以对Series、Dataframe使用
# 自动过滤NaN值
# df.columns是一个Index对象,也可使用.str
字符串常用方法(1) - lower,upper,len,startswith,endswith
print(s.str.lower(),'→ lower小写\n')
print(s.str.upper(),'→ upper大写\n')
print(s.str.len(),'→ len字符长度\n')
print(s.str.startswith('b'),'→ 判断起始是否为a\n')
print(s.str.endswith('3'),'→ 判断结束是否为3\n')
字符串常用方法(2) - strip
print(s.str.strip()) # 去除字符串中的空格
print(s.str.lstrip()) # 去除字符串中的左空格
print(s.str.rstrip()) # 去除字符串中的右空格
字符串常用方法(3) - replace
字符串常用方法(4) - split、rsplit
字符串索引
merge , join
merge合并 → 类似excel的vlookup
参数how → 合并方式
pd.merge(df3, df4,on=['key1','key2'], how = 'inner')
inner:默认,取交集
outer:取并集,数据缺失范围NaN
left:按照df3为参考合并,数据缺失范围NaN
right:按照df4为参考合并,数据缺失范围NaN
参数 left_on, right_on, left_index, right_index → 当键不为一个列时,可以单独设置左键与右键
参数 sort
参数how → 合并方式
参数 left_on, right_on, left_index, right_index → 当键不为一个列时,可以单独设置左键与右键
sort
pd.join() → 直接通过索引链接
concat, combine_first
连接:concat
默认axis=0,行+行
axis=1,列+列,成为一个Dataframe
连接方式:join,join_axes
# join:{'inner','outer'},默认为“outer”。如何处理其他轴上的索引。outer为联合和inner为交集。
# join_axes:指定联合的index
覆盖列名
keys:序列,默认值无。使用传递的键作为最外层构建层次索引
axis = 1, 覆盖列名
修补 pd.combine_first()
# 根据index,df1的空值被df2替代
# 如果df2的index多于df1,则更新到df1上,比如index=['a',1]
去重和替换
去重 .duplicated
s.duplicated()
判断是否重复
s[s.duplicated() == False]
通过布尔判断,得到不重复的值
drop.duplicates移除重复
inplace参数:是否替换原值,默认False
替换 .replace
# 可一次性替换一个值或多个值
# 可传入列表或字典
数据分组
分组
分组统计 - groupby功能
① 根据某些条件将数据拆分成组
② 对每个组独立应用函数
③ 将结果合并到一个数据结构中
Dataframe在行(axis=0)或列(axis=1)上进行分组,将一个函数应用到各个分组并产生一个新值,然后函数执行结果被合并到最终的结果对象中。
df.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)
分组 - 可迭代对象
其他轴上的分组
通过字典或者Series分组
通过函数分组
分组计算函数方法
print(grouped.first(),'→ first:非NaN的第一个值\n')
print(grouped.last(),'→ last:非NaN的最后一个值\n')
print(grouped.sum(),'→ sum:非NaN的和\n')
print(grouped.mean(),'→ mean:非NaN的平均值\n')
print(grouped.median(),'→ median:非NaN的算术中位数\n')
print(grouped.count(),'→ count:非NaN的值\n')
print(grouped.min(),'→ min、max:非NaN的最小值、最大值\n')
print(grouped.std(),'→ std,var:非NaN的标准差和方差\n')
print(grouped.prod(),'→ prod:非NaN的积\n')
多函数计算:agg()
print(df.groupby('a')['b'].agg({'result1':np.mean,'result2':np.sum}))
分组转换及一般性“拆分-应用-合并”
数据分组转换,transform
通过分组、合并,得到一个包含均值的Dataframe
一般化Groupby方法:apply
pandas.cut
用来把一组数据分割成离散的区间。
透视表及交叉表
透视表:pivot_table
pd.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
# data:DataFrame对象
# values:要聚合的列或列的列表
# index:数据透视表的index,从原数据的列中筛选
# columns:数据透视表的columns,从原数据的列中筛选
# aggfunc:用于聚合的函数,默认为numpy.mean,支持numpy计算方法
# 这里就分别以date、key共同做数据透视,值为values:统计不同(date,key)情况下values的平均值
# aggfunc=len(或者count):计数
交叉表:crosstab
# 默认情况下,crosstab计算因子的频率表,比如用于str的数据透视分析
# pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True, normalize=False)
# 如果crosstab只接收两个Series,它将提供一个频率表。
# 用A的唯一值,统计B唯一值的出现次数
# normalize:默认False,将所有值除以值的总和进行归一化 → 为True时候显示百分比
# values:可选,根据因子聚合的值数组
# aggfunc:可选,如果未传递values数组,则计算频率表,如果传递数组,则按照指定计算
# 这里相当于以A和B界定分组,计算出每组中第三个系列C的值
# margins:布尔值,默认值False,添加行/列边距(小计)
文件读取
读取普通分隔数据:read_table
可以读取txt,csv
# delimiter:用于拆分的字符,也可以用sep:sep = ','
# header:用做列名的序号,默认为0(第一行)
# index_col:指定某列为行索引,否则自动索引0, 1, .....
# read_table主要用于读取简单的数据,txt/csv
读取csv数据:read_csv
# 先熟悉一下excel怎么导出csv
# 大多数情况先将excel导出csv,再读取
# 读取excel数据:read_excel
# io :文件路径。
# sheetname:返回多表使用sheetname=[0,1],若sheetname=None是返回全表 → ① int/string 返回的是dataframe ②而none和list返回的是dict
# header:指定列名行,默认0,即取第一行
# index_col:指定列为索引列,也可以使用u”strings”