Pandas

Pandas(panel data & Data Analysis):最流行的Python数据分析库


import pandas as pd


基于Numpy,专用于数据预处理和数据分析的Python第三方库,最适合处理大型结构化表格数据

  • Series 一维,带标签数组
  • DataFrame 二维,Series容器,最常用
  • Panel 三维,DataFrame容器

list:Python自带数据类型,功能简单,操作复杂,效率低
ndarray:基础数据类型,关注数据结构/运算/维度(数据间关系)
Series/DataFrame:扩展数据类型,关注数据与索引的关系,数据实际应用

从实用性、功能强弱和和可操作性比较:list < ndarray < Series/DataFrame
实践工作中,ndarry数组作为必要补充,大部分数据尽量使用Pandas数据类型


// 数据类型

# Series 一维
pd.Series([2,4], index=['周', '孔'])
pd.Series(
    {
    'hong':50,
     'huang':90,
    }
)

# 取值
.loc('索引', 列)

# 取索引的值
.index()

# 取值

# 查询多值
a[[1,3,4]]

# 位置切片,默认索引,左闭右开
b[:3]

# 标签切片,自定义索引
# 注意:两边都闭区间(因为使用标签索引时通常不知道标签顺序,很难确定结束前一个标签是什么)
b[:'huang'] 
b['huang':]

# 步长
b[::2] 
b[::-1] #步长-1,逆序

# 过滤
b >= 60
b[b >= 60]

# 标量算数运算
b + 1

# 应用函数
np.median(b) # 中位数
b.median() # 方法调用写法

'c' in b # 判断此键在不在b的索引中
# 0 in b # 错误,in不会判断自动索引

b.get('zi',60) #从b中提取索引zi的值,如果存在就取出,不存在用60代替

# values值修改
b['ming'] = 0

b['hua','hong'] = 55 # b[['hua','hong']] = 20
b['hua','hong'] = [35,55]
b

# 索引修改
b2 = b.copy() # 复制副本而非引用视图,类似深拷贝
b2.index = ['xiaoming','xiaohua','xiaohong','xiaohuang','xiaobai']

# Series对象和索引命名
s.index
s.name

// 数据类型-DataFrame
DataFrame对象是Pandas最常用的数据类型

  • 表格型数据结构,类似EXCEL或关系型数据库中的二维表,实际应用非常广泛
  • DataFrame对象是由多个Series对象作为列组成的表格数据类型,每行Series值都增加了一个共用的索引
  • 是Series对象的容器,可视为:二维的带标签数组,或由Series组成的字典

DataFrame对象既有行索引,又有列索引

  • 行索引,表明不同行,横向索引,叫index,0轴,axis=0
  • 列索引,表名不同列,纵向索引,叫columns,1轴,axis=1

其他情况:

  • 基本操作类似Series,依据行列索引操作
  • 内存中以一个或多个二维块存放,而不是列表、字典或别的一维数据结构
  • 常用于表达二维数据,但也可以表达多维数据(层次化索引的表格型结构)

(等长)列表或Numpy数组组成的字典 创建DataFrame,注意必须等长否则报错

# 二维数组, 索引和列名
pd.DataFrame([[2,4,6,8,10], [12,14,16,18,20]], index=['语文', '数学', '英语'], columns=['周', '孔', '王', '李'])

pd.DataFrame(
    ['小明','male',18,170,60,'北京海淀',61],
    ['小华','female',28,160,50,'上海静安',90],
    index=[1,2],                                                    # 行索引
    columns=['name','sex','age','heigh','weight','address','grade'] # 列索引
)

# 指定列排序
d = pd.DataFrame(cv,columns=['name','sex','age'])

# 传入列在数据中找不到,会产生NA值
e = pd.DataFrame(cv,index=[1,2,3,4,5],columns=['name','sex','age','heigh'])
------------------------------------------------------------------------------
# 嵌套字典(字典组成的字典) 创建DataFrame,不等长也可,自动填充NaN
# 外层键是列索引,内层键是行索引
fv = {
    'name':{1:'小明',2:'小华',3:'小红',4:'小青',5:'小兰'},
    'sex':{1:1,2:0,3:0,4:1,5:0},
    'age':{2:28,3:38,4:48,5:8} # 少一个值自动填充为Nan
}
f = pd.DataFrame(fv)

# 指定内层字典键(行索引),没有的值会填充NaN
g = pd.DataFrame(fv,index=[3,4,2,6])
---------------------------------------------------------------------------------
# Series组成的字典 创建DataFrame,同嵌套字典

# 外层键是列索引,内层键是行索引
hv = {
    'name':pd.Series(['小明','小华','小红','小靑','小兰'],index=[1,2,3,4,5]),
    'sex':pd.Series([1,0,0,1,0],index=[1,2,3,4,5]),
    'age':pd.Series([28,38,48,8],index=[2,3,4,5]) # 少一个值自动填充为NaN
}
h = pd.DataFrame(hv)


# 指定内层字典键(行索引),没有的值会填充NaN
i = pd.DataFrame(hv,index=[3,4,2,6])


# Series对象和索引命名
s
s.name #默认没有
s.name = 'uname' # Series对象命名
s
s.name

s.index
s.index.name = 'cname' # 索引命名
s
s.index
-------------------------------------------------------------------------------
# ndarray数组 创建DataFrame

# 自动生成行列索引
j = pd.DataFrame(np.arange(10).reshape(2,5)) 

# 自定义行列索引
k = pd.DataFrame(
    np.random.randn(6,4),
    index=[1,2,3,4,5,6],
    columns=['a','b','c','d']
)


# axis=1删除列,默认axis=0删除行
b.drop(['math','chinese'],axis=1)



# 遍历DataFrame
for index, row in a.iterrows():
#     print(index) # 行索引
#     print(row) # 值,按行排列
    print(row[0]) # 单元格

# 查看维度
a.shape

# 查看类型
a.dtypes

# 查看值
a.values

# 查询单值
a['name'][2]        # 必须先列后行

# 查看结构什么样的
a.head(3)            # 显示头部几行,默认5行
a.tail(3)            # 显示末尾几行,默认5行
a.info()             # 相关信息概览:行数,列数,列索引,列非空值个数,列类型,列类型,内存占用
a.describe()         # 快速综合统计结果:计数,均值,标准差,最大值,四分位数,最小值

# 索引查询
# 用于连续或不连续(行列有间隔)行列区块查询
# 解决了DataFrame进行行标签查询的问题
# 两种查询方式:
    #a.loc[行,列],标签索引,自定义索引
    #a.iloc[行,列],位置索引,默认索引
# 参数书写顺序都是都是先行后列

# 查询单行
a.loc[1] # 标签索引
a.iloc[1] # 位置索引,从0开始

# 查询单列
a.loc[:,'name'] # 标签索引
a.iloc[:,0] # 位置索引

# 查询多行,双中括号
a.loc[[2,4]] # 标签索引
a.iloc[[1,3]] # 位置索引

# 查询多列
a.loc[:,['name','address']] # 标签索引
a.iloc[:,[0,5]] # 位置索引

# 查询单个单元格
a.loc[1,'name'] # 标签索引,先行后列,一行一列
a.at[1,'name'] # 同上,但速度更快效率更高

a.iloc[0,0] # 位置索引
a.iat[0,0] # 同上,但速度更快效率更高

# 查询多个单元格
a.loc[1,['name','address']] # 一行多列,Series
a.loc[[1,3],'address'] # 多行一列,Series
a.loc[[1,3],['name','address']] # 多行多列,不连续,DataFrame

a.iloc[0,[0,5]]
a.iloc[[0,2],5]
a.iloc[[0,2],[0,5]]
# 切片查询
# 用于连续行列区块查询

# 比索引查询简单方便,但不能查询非连续行列区块
# 单个或不连续行列区块使用索引查询,连续行列区块使用切片查询
# 切片查询的区间:

# iloc 默认位置索引是左闭右开区间(包含起始元素,不包含结束元素)
# loc 自定义标签索引是左闭右闭区间(包含起始元素,也包含结束元素)
# 因为标签索引不包含位置信息,使用时很难知道索引前后是什么

# 选取一行
a.loc[2,:] # 等价于 a.loc[2]
a.iloc[1,:] # 等价于 a.iloc[1]

# 选取一列
a.loc[:,'sex']
a.iloc[:,1]

# 切片选取连续多行
a.loc[:3,:] # 左闭右闭
a.iloc[:3,:] # 左闭右开

# 切片选取连续多列
a.loc[:,'heigh':'address']
a.iloc[:,3:6]

# 切片选取多行多列的聚合
a.loc[3:5,'sex':'heigh'] 
a.iloc[2:5,1:4]
# 过滤查询

# 通过列布尔值过滤、筛选查询
# 不通过索引而是通过值查询
# 用于结果索引不确定的查询
# 通过运算所得布尔值对查询结果进行过滤
# 通过某列值过滤数据,返回布尔值
a['grade'] >= 60
a.loc[:,'grade'] >= 60

# 布尔值做DataFrame参数,返回Dataframe对象
a[a['grade'] >= 60]
a[a.loc[:,'grade'] >= 60]

# 布尔索引和切片结合
a.loc[a['grade'] > 60,'address':] # 行,列



# 多重条件过滤,逻辑运算
# & 且
# | 或
# - 非(或用 != 判断)
(a['grade'] >= 60) & (a['sex'] == 'female')
a[(a['grade'] >= 60) & (a['sex'] == 'female')]

# 通过where过滤选取数据
a > 60
a < 30

a[a > 60]
a[a < 30]

# where过滤
dColumns = a[['name','weight','grade']] # 获取3列数据
dBool = dColumns > 60 # 判断布尔值
dNan = dColumns[dBool] # 过滤查询
dNan
dNan.dropna(how='any') # 丢掉含有缺失值的行

# 通过isin()过滤选取数据
# 查询某列中包含某值的所有行
a['address'].isin(['北京海淀','深圳南山'])
a[a['address'].isin(['北京海淀','深圳南山'])]
# 修改,Update


# 凡能通过查询得到的值,直接赋值就可修改
# 视图和副本: 通过索引和切片返回的数据是原数据的视图,不是副本,任何对视图的修改全部会反映到源数据上,想独立修改数据可以通过copy()复制源数据的副本
# 类list/ndarray查询方式修改
b = a.copy()
b

b['heigh']
b['heigh'] = 170
b['heigh'] = [150,160,170,180,190]
b

# 索引或切片查询方式修改
b.loc[[1,3,5],['age','heigh']]
b.loc[[1,3,5],['age','heigh']] = [[10,100],[20,200],[30,300]] # 3行2列
# b.loc[[1,3,5],['age','heigh']] = [[1,2,3],[4,5]] # 错误,维度不匹配
b

# 通过where过滤修改
b[b > 60]
b[b > 60] = 1 # 错误,不能在混合数据类型中修改非NaN值

# 提取唯一数据类型数据
c = a.loc[:,['weight','grade']].copy()
c2 = c.copy()
c

c > 60
c[c > 60]
c[c > 60] = 1 # 修改非NaN值
c

-(c2 > 60) # 非,或 c2 <= 60
c2[-(c2 > 60)] = 1
c2
# 删除,Delete

# Series对象删除值
s.drop('ming')

# DataFrame对象删除值
# 默认删除行,默认只改动视图
b.drop(1) # 删除单行
b.drop([1,7]) # 删除多行

# 删除列
# axis=1删除列,默认axis=0删除行
b.drop('math',axis=1)
b.drop(['math','chinese'],axis=1)


# inplace=True 改动原数据,默认inplace=False 只改动视图
b.drop(['math','chinese'],axis=1,inplace=True)


# DataFrame对象的索引命名
b.index.name = 'hang'
b.columns.name = 'lie'

这里写图片描述


Pandas数据存取

Pandas可以存取多种介质类型数据,例如:内存、文本、CSV、JSON、HTML、Excel、HDF5、SQL等

# 写入CSV
# 数据有中文,编码可以修改,默认ascii,改为utf-8
# 写入不修改编码则读取时需要修改
df.to_csv(
    'foo2.csv', # 存入数据
    index=False, # 不存储行索引
    header=False, # 不存储列索引
    encoding='utf-8' # 修改编码
)

# 读取CSV
# csv文件内有汉字等特殊符号时,csv文件编码应为utf-8(无BOM)可默认正常读取,如果编码是ANSI,加参数encoding='gbk'
# 数据内有逗号时,左右加英文半角双引号,可以正常解析
pd.read_csv(
    'foo2.csv', # 文件名
    sep=',', # 指定分隔符,csv默认逗号,如果是table表格数据一般为 \t
    usecols=[0,1,2,4], # 读取指定列
    nrows=10, # 读取前几行
    header=None, # 不将第一行设为表头
    names=['a','b','c','d'], # 不使用csv表头,自定义表头
    encoding='utf-8' # 编码,需要根据文本编码修改,默认utf-8,可以指定为GBK/ascii
)

# 合并时间列及自定义某列为行索引
'''
data,time,name,age
20100101,000000,"张三",18
20100101,230000,"李,四",28
'''

pd.read_csv(
    'foo.csv',
    parse_dates={'shijian': ['data','time']}, #将两列合并解析为时间格式
    index_col='shijian', #将某列设为行索引
)
# Pandas存取HDF5
# 有中文,存储变的异常的大

# 写入HDF5
df.to_hdf('foo.h5','df')

# 从HDF5读取
pd.read_hdf('foo.h5','df')
一个h5文件可写入多个变量

a.to_hdf('foo.h5','abc')

pd.read_hdf('foo.h5','abc')
# Pandas存取Excel(xlsx)

# 写入Excel文件
df.to_excel(
    'foo.xlsx', # 写入数据
    'Sheet1', # 工作表标签
    header=False, # 不存入列索引
    index=False # 不存入行索引
)

# 从Excel文件读取
# 分别读取
pd.read_excel('output.xlsx', 'Sheet1', index_col=None, na_values=['NA'],header=None) # 不将第一行设为表头
pd.read_excel('output.xlsx', 'Sheet2', index_col=None, na_values=['NA'])
# Pandas存取JSON

# 存入JSON
a.to_json('foo.json')

# 读取JSON
pd.read_json('foo.json')
# Pandas从剪贴板(内存)读取数据

# 多用于将网页内容转换为DataFrame
pd.read_clipboard()

# 不将第一行设为表头
pd.read_clipboard(header=None) 

// Pandas存取数据库

这里写图片描述

from sqlalchemy import create_engine

# 连接MySQL数据库,需要安装Python连接库
# conda install -c anaconda pymysql 

dbconnect = 'pymysql'            # MySQL连接库,根据使用的连接库修改名称,这里用pymysql
dbname = 'aaa'                   # 数据库名
dbusername = 'root'              # 数据库用户名
dbpwd = 'root'                   # 数据库密码

# 连接数据库
conn = create_engine('mysql+' + dbconnect + '://' + dbusername + ':' + dbpwd + '@localhost:3306/' + dbname + '?charset=utf8')
# 存取数据库数据

# 查询数据库

sql1 = 'SELECT * FROM ccc'

df1 = pd.read_sql( # pd.io.sql.read_sql()的快捷方式
    sql1, # sql语句
    conn, # 数据库连接
    index_col='id' # 选定某列做行索引,可选
)
df1

# 插入数据库

a

pd.io.sql.to_sql(
    a, # 插入的数据,注意格结构应和MySQL表一致
    'ccc', # 表名
    con=conn, # 数据库连接
    if_exists='append', # 注释见下
    index=False # 不将列索引插入数据库中,否则会出错
)

这里写图片描述


// Pandas统计分析

pandas数据的基本统计分析和numpy的函数近似

dates = pd.date_range('20130101',periods=10)
dates
df = pd.DataFrame(np.random.randn(10,4),index=dates,columns=['A','B','C','D'])
df

df.describe() #快速统计结果
df.mean() # 按列求平均值
df.mean(1) # 按行求平均值

这里写图片描述

a.argmin()
b.idxmin()

a = pd.Series([9,8,7,6],index=['a','b','c','d'])
a
b = pd.DataFrame(np.arange(20).reshape(4,5),index=['c','a','d','b'])
b

a.describe()
type(a.describe()) #series对象
a.describe()['count']

b.describe() #默认0轴运算
type(b.describe()) #dataframe对象

#返回横行数据,series
b.describe().loc['max']
b.describe().iloc[7]

#返回一列值,这里第2列
b.describe()[2]
#b.describe()[2]
b.describe().loc[:,2]

数据的累计统计分析

  • 对序列的前1-n个数累计运算
  • 可减少for循环的使用

可用于金融数据分析中的计算累计盈亏
这里写图片描述

滚动计算(窗口计算)函数

可用于金融数据分析中的计算每笔盈亏
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葬爱程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值