python--pandas统计分析基础
pandas统计分析基础
- 读/写不同数据源的数据
- 读/写数据库数据
- 数据库数据读取
- 数据库数据存储
- 读/写文本文件
- 文本文件读取
- 文本文件存储
- 读/写Excel文件
- Excel文件读取
- Excel文件存储
- 任务实现
- DataFrame的常用操作
- 查看DataFrame的常用属性
- 增删改查DataFrame数据
- 查看访问DataFrame中的数据
- DataFrame数据的基本查看方式
- DataFrame的loc、iloc访问方式
- 切片方法之ix
- 更改DataFrame中的数据
- 为DataFrame增添数据
- 删除某行或某列数据
- 描述分析DataFrame数据
- 数值型特征的描述性统计
- 类别型数据的描述性统计
- 任务实现
- 转换与处理时间系列数据
- 转换字符串时间为标准时间
- 提取时间序列数据信息
- 加减时间数据
- 任务实现
- 使用分组聚合进行组内计算
- 使用groupby方法拆分数据
- 使用agg方法聚合数据
- 使用apply方法聚合数据
- 使用transform方法聚合数据
- 任务实现
- 创建透视表与交叉表
- 使用pivot_table函数创建透视表
- 使用crosstab函数创建交叉表
- 任务实现
读/写不同数据源的数据
读/写数据库数据
- pandas提供了读取与存储关系型数据库数据的函数与方法。除了pandas库外还需要使用SQLAlchemy库建立对应数据库连接。SQLAlchemy配合相应数据库的python连接工具,使用create_engine函数,建立一个数据库连接。
数据库数据读取
- 方法:pandas.read_sql_table:只能够读取数据库的某一个表格,不能实现查询的操作;pandas.read_sql_query:只能实现查询操作,不能直接读取数据库的某一个表格;pandas.read_sql:既能读取数据库中的某一个表,也能够实现查询操作。
pandas.read_sql_table(table_name,con,schema=None,index_col=None,coerce_float=True,columns=None) pandas.read_sql_query(sql,con,index_col=None,coerce_float=True) pandas.read_sql(sql,con,index_col=None,coerce_float=True,columns=None)
在creat_engine中输入的时一个连接字符串。在使用Python的SQLAlchemy时,MySQL和Oracle数据库连接字符串的格式:数据库产品名+连接工具名://用户名:密码@数据库IP地址:数据库端口号/数据库名称?charset=数据库数据编码
pandas.read_sql_table、pandas.read_sql_query、pandas.read_sql函数参数及其重要参数说明
C参数名称 | 说明 |
---|---|
sql or table_name | 接收string。表示读取的数据的表名或者SQL语句。无默认 |
con | 接收数据库连接。表示数据库连接信息。无默认 |
index_col | 接收int、sequence或者False。表示设定的列作为行名,如果是一个数列,则是多重索引。默认为None |
coerce_float | 接收boolean。将数据库中的decimal类型的数据转换为pandas中的float64类型的数据。默认为None |
columns | 接收list。表示读取数据的列名。默认为None |
- SQLAlchemy连接MySQL数据库
from sqlalchemy import create_engine
# 创建一个mysql连接器,用户名为root,密码为1234
# 地址为127.0.0.1,数据库名称为testdb,编码为utf-8
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/testdb?charset=utf8')
print(engine)
Engine(mysql+pymysql://root:***@127.0.0.1:3306/testdb?charset=utf8)
- 读取数据库数据
import pandas as pd
# 使用read_sql_query查看wyc中的数据表数目
formlist = pd.read_sql_query('show tables', con = engine)
print('testdb数据库数据表清单为:','\n',formlist)# 使用read_sql_table读取订单详情表
detail1 = pd.read_sql_table('meal_order_detail1',con = engine)
print('使用read_sql_table读取订单详情表的长度为:',len(detail1))# 使用read_sql读取订单详情表
detail2 = pd.read_sql('select * from meal_order_detail2',con = engine)
print('使用read_sql函数+sql语句读取的订单详情表长度为:',len(detail2))
detail3 = pd.read_sql('meal_order_detail3',con = engine)
print('使用read_sql函数+表格名称读取的订单详情表长度为:',len(detail3))
testdb数据库数据表清单为: Tables_in_testdb
0 meal_order_detail1
1 meal_order_detail2
2 meal_order_detail3
使用read_sql_table读取订单详情表的长度为: 2779
使用read_sql函数+sql语句读取的订单详情表长度为: 3647
使用read_sql函数+表格名称读取的订单详情表长度为: 3611
数据库数据存储
- 将DataFrame写入数据库中,依赖于SQLAlchemy库的create_engine函数创建数据库连接。语法:
DataFrame.to_sql(name,con,schema=None,if_exists='fail',index=True,index_label=None,dtype=None)
to_sql方法常用参数及其说明
参数名称 | 说明 |
---|---|
name | 接收string。代表数据库表名。无默认 |
con | 接收数据库连接。无默认 |
if_exists | 接收fail、replace和append。fail表示如果表名存在,则不执行写入操作;replace表明如果存在,则将原数据库表删除,再重新创建,则不执行写入操作;append表示再原数据库表的基础上追加数据。默认为fail |
index | 接收boolean。表示是否将行索引作为数据传入数据库。默认为True |
index_label | 接收string或者sequence。代表是否引用索引名称,如果index参数为True,此参数为None,则使用默认名称。如果为多重索引,则必须使用sequence形式。默认为None。 |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None |
- 数据库存储数据
# 使用to_sql存储orderData
detail1.to_sql('test1',con = engine,index = False,if_exists = 'replace')
# 使用read_sql读取test表
formlist1 = pd.read_sql_query('show tables',con = engine)
print('新增一个表格后testdb数据库数据表清单为:','\n',formlist1)
新增一个表格后testdb数据库数据表清单为: Tables_in_testdb
0 meal_order_detail1
1 meal_order_detail2
2 meal_order_detail3
3 test1
读/写文本文件
文本文件:由若干行字符构成的计算机文件,典型的顺序文件;CSV:用分隔符分隔的文件格式,文字分隔文件。
文本文件读取
- pandas提供了read_table函数来读取文本文件,read_csv函数来读取CSV文件。语法:
pandas.read_table(filepath,sep='\t',header='infer',names=None,index_col=None,dtype=None,encoding=utf-8,engine=None,nrows=None) pandas.read_csv(filepath,sep='\t',header='infer',names=None,index_col=None,dtype=None,encoding=utf-8,engine=None,nrows=None)
read_table和read_csv常用参数及其说明
参数名称 | 说明 |
---|---|
filepath | 接收string。代表文件路径。无默认 |
sep | 接收string。代表分隔符。read_csv默认为“,”,read_table默认为制表符“Tab” |
header | 接收int或sequence。表示将某列数据作为列名。默认为infer,表示自动识别 |
names | 接收array。表示列名。默认为None |
index_col | 接收int、sequence或False。表示索引列的位置,取值为sequence则代表多重索引。默认为None |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None |
engine | 接收c或者python。代表数据解析引擎。默认为c |
nrows | 接收int。表示读取前n行。默认为None |
- 文本文件读取
# 使用read_table读取订单信息表
order = pd.read_table('./data/meal_order_info.csv',sep = ',',encoding = 'gbk')
print('使用read_table读取的订单信息表的长度为:',len(order))# 使用read_csv读取订单信息表
order1 = pd.read_csv('./data/meal_order_info.csv',encoding = 'gbk')
print('使用read_csv读取的订单信息表的长度为:',len(order1))
使用read_table读取的订单信息表的长度为: 945
使用read_csv读取的订单信息表的长度为: 945
# 使用read_table读取菜品订单信息表,sep = ';'
order2 = pd.read_table('./data/meal_order_info.csv',sep = ';',encoding = 'gbk')
print('分隔符为;时订单信息表为:\n',order2.head(5))# 使用read_csv读取菜品订单信息表,header=None
order3 = pd.read_csv('./data/meal_order_info.csv',sep = ',',header = None,encoding = 'gbk')
print('订单信息表为:','\n',order3.head(5))# 使用gbk解析菜品订单信息表
order4 = pd.read_csv('./data/meal_order_info.csv',sep = ',',encoding = 'utf-8')
分隔符为;时订单信息表为:info_id,"emp_id","number_consumers","mode","dining_table_id","dining_table_name","expenditure","dishes_count","accounts_payable","use_start_time","check_closed","lock_time","cashier_id","pc_id","order_number","org_id","print_doc_bill_num","lock_table_info","order_status","phone","name"
0 417,1442,4,NA,1501,1022,165,5,165,"2016/8/1 11...
1 301,1095,3,NA,1430,1031,321,6,321,"2016/8/1 11...
2 413,1147,6,NA,1488,1009,854,15,854,"2016/8/1 1...
3 415,1166,4,NA,1502,1023,466,10,466,"2016/8/1 1...
4 392,1094,10,NA,1499,1020,704,24,704,"2016/8/1 ...
订单信息表为: 0 1 2 3 4 \
0 info_id emp_id number_consumers mode dining_table_id
1 417 1442 4 NaN 1501
2 301 1095 3 NaN 1430
3 413 1147 6 NaN 1488
4 415 1166 4 NaN 1502 5 6 7 8 \
0 dining_table_name expenditure dishes_count accounts_payable
1 1022 165 5 165
2 1031 321 6 321
3 1009 854 15 854
4 1023 466 10 466 9 ... 11 12 13 14 \
0 use_start_time ... lock_time cashier_id pc_id order_number
1 2016/8/1 11:05:36 ... 2016/8/1 11:11:46 NaN NaN NaN
2 2016/8/1 11:15:57 ... 2016/8/1 11:31:55 NaN NaN NaN
3 2016/8/1 12:42:52 ... 2016/8/1 12:54:37 NaN NaN NaN
4 2016/8/1 12:51:38 ... 2016/8/1 13:08:20 NaN NaN NaN 15 16 17 18 19 \
0 org_id print_doc_bill_num lock_table_info order_status phone
1 330 NaN NaN 1 18688880641
2 328 NaN NaN 1 18688880174
3 330 NaN NaN 1 18688880276
4 330 NaN NaN 1 18688880231 20
0 name
1 苗宇怡
2 赵颖
3 徐毅凡
4 张大鹏 [5 rows x 21 columns]
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-12-da6c18e298dd> in <module>8 9 # 使用gbk解析菜品订单信息表
---> 10 order4 = pd.read_csv('./data/meal_order_info.csv',sep = ',',encoding = 'utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 401: invalid continuation byte
文本文件存储
- 语法:
DataFrame.to_csv(path_or_buff=None,sep=',',na_rep='',columns=None,header=True,index=True,index_label=None,mode='w',encoding=None)
to_csv函数常用参数及其说明
参数名称 | 说明 |
---|---|
path_or_buff | 接收string。代表文件路径。无默认 |
sep | 接收string。代表分隔符。默认为‘,’ |
na_rep | 接收string。代表缺失值。默认为“” |
columns | 接收list。代表写出的列名。默认为None |
header | 接收boolean。代表是否将列名写出。默认为True |
index | 接收boolean。代表是否将列名写出。默认为True |
index_label | 接收sequence。表示索引名。默认为None |
mode | 接收特定string。代表数据写入模式。默认为v |
encoding | 接收特定string。代表存储文件的编码格式。默认为None |
- 文本文件存储
import os
print('订单信息表写入文本文件前目录内文件列表为:\n',os.listdir('./data'))
# 将order以csv格式存储
order.to_csv('./data/orderInfo.csv',sep = ';',index = False)
print('订单信息表写入文本文件后目录内文件列表为:\n',os.listdir('./data'))
订单信息表写入文本文件前目录内文件列表为:
[]
订单信息表写入文本文件后目录内文件列表为:
[orderInfo.csv]
读/写Excel文件
Excel文件读取
- 读取“xls” “xlsx”两种Excel文件。语法:
pandas .read_excel(io,sheetname=,header=,index_col=None,dtype=None)
read_excel函数的常见参数及其说明
参数名称 | 说明 |
---|---|
io | 接收string。表示文件路径。无默认 |
sheetname | 接收string、int。代表Excel表内数据的分表位置。默认为0 |
header | 接收int或sequence。表示将某行数据作为列名,取值为int的时候,代表将该列作为列名。取值为sequence时,则代表多重列索引。默认为infer,表示自动识别 |
names | 接收array。表示列名。默认为None |
index_col | 接收int、sequence或者False。表示索引列的位置,取值为sequence时代表多重索引。默认为None |
dtype | 接收dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None |
- Excel文件读取
user = pd.read_excel('./data/users.xlsx') # 读取user.xlsx文件
print('客户信息表长度为:',len(user))
客户信息表长度为: 734
Excel文件存储
语法:
DataFrame.to_excel(excel_writer=None,sheetname='None',na_rap='',header=True,index=True,index_label=None,mode='w',encoding=None)
\
print('客户信息表写入excel文件前目录内文件列表为:\n',os.listdir('./data'))
user.to_excel('../tmp/userInfo.xlsx')
print('客户信息表写入excel文件后目录内文件列表为:\n',os.listdir('./data'))
客户信息表写入excel文件前目录内文件列表为:
['orderInfo.csv']
客户信息表写入excel文件后目录内文件列表为:
['orderInfo.csv','userInfo.xlsx']
任务实现
- 读取订单详情数据库数据
# 导入SQLAlchemy库的creat_engine函数
from sqlalchemy import create_engine
import pandas as pd
# 创建一个mysql连接器,用户名为root,密码为1234
# 地址为127.0.0.1,数据库名称为testdb
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:\
3306/testdb?charset=utf8')
# 使用read_sql_table读取订单详情表格
order1 = pd.read_sql_table('meal_order_detail1',con = engine)
print('订单详情表1的长度为:',len(order1))
order2 = pd.read_sql_table('meal_order_detail2',con = engine)
print('订单详情表2的长度为:',len(order2))
order3 = pd.read_sql_table('meal_order_detail3',con = engine)
print('订单详情表3的长度为:',len(order3))
订单详情表1的长度为: 2779
订单详情表2的长度为: 3647
订单详情表3的长度为: 3611
- 读取订单信息csv数据
# 使用read_table读取订单信息表
orderInfo = pd.read_table('./data/meal_order_info.csv',sep = ',',encoding = 'gbk')
print('订单信息表的长度为:',len(orderInfo))
订单信息表的长度为: 945
- 读取客户信息Excel数据
# 读取user.xlsx文件
userInfo = pd.read_excel('./data/users.xlsx', sheetname = 'users1')
print('客户信息表的长度为:',len(userInfo))
客户信息表的长度为:734
DataFrame的常用操作
查看DataFrame的常用属性
- DataFrame基础属性由values、index、columns和dtype,分别可以获取元素、索引、列名和类型。
from sqlalchemy import create_engine
import pandas as pd
# 创建数据库连接
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/testdb?charset=utf8')
detail= pd.read_sql_table('meal_order_detail1',con = engine)
print('订单详情表的索引为:', detail.index)
print('订单详情表的所有值为:','\n', detail.values)
print('订单详情表的列名为:','\n', detail.columns)
print('订单详情表的数据类型为:','\n', detail.dtypes)
from sqlalchemy import create_engine
import pandas as pd
# 创建数据库连接
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/testdb?charset=utf8')
detail= pd.read_sql_table('meal_order_detail1',con = engine)
print('订单详情表的索引为:', detail.index)
print('订单详情表的所有值为:','\n', detail.values)
print('订单详情表的列名为:','\n', detail.columns)
print('订单详情表的数据类型为:','\n', detail.dtypes)
- size:元素个数;ndim:维度数;shape:数据形状
# 查看DataFrame的元素个数
print('订单详情表的元素个数为:', detail.size)
print('订单详情表的维度数为:', detail.ndim) ## 查看DataFrame的维度数
print('订单详情表的形状为:', detail.shape) ## 查看DataFrame的形状
订单详情表的元素个数为: 52801
订单详情表的维度数为: 2
订单详情表的形状为: (2779, 19)
- DataFrame转置
print('订单详情表转置前形状为:',detail.shape)
print('订单详情表转置后形状为为:',detail.T.shape)
订单详情表转置前形状为: (2779, 19)
订单详情表转置后形状为为: (19, 2779)
增删改查DataFrame数据
查看访问DataFrame中的数据
DataFrame数据的基本查看方式
- 使用字典访问内部数据的方法访问DataFrame单列数据
order_id = detail['order_id']
print('订单详情表中的order_id的形状为:','\n',order_id.shape)
订单详情表中的order_id的形状为: (2779,)
- 使用访问属性和的方法访问DataFrame单列数据
dishes_name = detail.dishes_name
print('订单详情表中的dishes_name的形状为:',dishes_name.shape)
订单详情表中的dishes_name的形状为: (2779,)
- DataFrame单列多行数据获取
dishes_name5 = detail['dishes_name'][:5]
print('订单详情表中的dishes_name前5个元素为:','\n',dishes_name5)
订单详情表中的dishes_name前5个元素为: 0 蒜蓉生蚝
1 蒙古烤羊腿\r\n\r\n\r\n
2 大蒜苋菜
3 芝麻烤紫菜
4 蒜香包
Name: dishes_name, dtype: object
- 访问DataFrame多列的多行数据
orderDish = detail[['order_id','dishes_name']][:5]
print('订单详情表中的order_id和dishes_name前5个元素为:','\n',orderDish)
订单详情表中的order_id和dishes_name前5个元素为: order_id dishes_name
0 417 蒜蓉生蚝
1 417 蒙古烤羊腿\r\n\r\n\r\n
2 417 大蒜苋菜
3 417 芝麻烤紫菜
4 417 蒜香包
- 访问DataFrame多行数据
order5 = detail[:][1:6]
print('订单详情表的1-6行元素为:','\n',order5)
订单详情表的1-6行元素为: detail_id order_id dishes_id logicprn_name parent_class_name \
1 2958 417 609957 NA NA
2 2961 417 609950 NA NA
3 2966 417 610038 NA NA
4 2968 417 610003 NA NA
5 1899 301 610019 NA NA dishes_name itemis_add counts amounts cost place_order_time \
1 蒙古烤羊腿\r\n\r\n\r\n 0 1 48 NA 2016-08-01 11:07:07.000
2 大蒜苋菜 0 1 30 NA 2016-08-01 11:07:40.000
3 芝麻烤紫菜 0 1 25 NA 2016-08-01 11:11:11.000
4 蒜香包 0 1 13 NA 2016-08-01 11:11:30.000
5 白斩鸡 0 1 88 NA 2016-08-01 11:15:57.000 discount_amt discount_reason kick_back add_inprice add_info bar_code \
1 NA NA NA 0 NA NA
2 NA NA NA 0 NA NA
3 NA NA NA 0 NA NA
4 NA NA NA 0 NA NA
5 NA NA NA 0 NA NA picture_file emp_id
1 caipu/202003.jpg 1442
2 caipu/303001.jpg 1442
3 caipu/105002.jpg 1442
4 caipu/503002.jpg 1442
5 caipu/204002.jpg 1095
- 使用DataFrame的head和tail方法获取多行
print('订单详情表中前五行数据为','\n',detail.head())
print('订单详情表中后五个元素为:','\n',detail.tail())
订单详情表中前五行数据为 detail_id order_id dishes_id logicprn_name parent_class_name \
0 2956 417 610062 NA NA
1 2958 417 609957 NA NA
2 2961 417 609950 NA NA
3 2966 417 610038 NA NA
4 2968 417 610003 NA NA dishes_name itemis_add counts amounts cost place_order_time \
0 蒜蓉生蚝 0 1 49 NA 2016-08-01 11:05:36.000
1 蒙古烤羊腿\r\n\r\n\r\n 0 1 48 NA 2016-08-01 11:07:07.000
2 大蒜苋菜 0 1 30 NA 2016-08-01 11:07:40.000
3 芝麻烤紫菜 0 1 25 NA 2016-08-01 11:11:11.000
4 蒜香包 0 1 13 NA 2016-08-01 11:11:30.000 discount_amt discount_reason kick_back add_inprice add_info bar_code \
0 NA NA NA 0 NA NA
1 NA NA NA 0 NA NA
2 NA NA NA 0 NA NA
3 NA NA NA 0 NA NA
4 NA NA NA 0 NA NA picture_file emp_id
0 caipu/104001.jpg 1442
1 caipu/202003.jpg 1442
2 caipu/303001.jpg 1442
3 caipu/105002.jpg 1442
4 caipu/503002.jpg 1442
订单详情表中后五个元素为: detail_id order_id dishes_id logicprn_name parent_class_name dishes_name \
2774 6750 774 610011 NA NA 白饭/大碗
2775 6742 774 609996 NA NA 牛尾汤
2776 6756 774 609949 NA NA 意文柠檬汁
2777 6763 774 610014 NA NA 金玉良缘
2778 6764 774 610017 NA NA 酸辣藕丁 itemis_add counts amounts cost place_order_time discount_amt \
2774 0 1 10 NA 2016-08-10 21:56:24.000 NA
2775 0 1 40 NA 2016-08-10 21:56:48.000 NA
2776 0 1 13 NA 2016-08-10 22:01:52.000 NA
2777 0 1 30 NA 2016-08-10 22:03:58.000 NA
2778 0 1 33 NA 2016-08-10 22:04:30.000 NA discount_reason kick_back add_inprice add_info bar_code \
2774 NA NA 0 NA NA
2775 NA NA 0 NA NA
2776 NA NA 0 NA NA
2777 NA NA 0 NA NA
2778 NA NA 0 NA NA picture_file emp_id
2774 caipu/601005.jpg 1138
2775 caipu/201006.jpg 1138
2776 caipu/404005.jpg 1138
2777 caipu/302003.jpg 1138
2778 caipu/302006.jpg 1138
DataFrame的loc、iloc访问方式
- loc使用方法:
DataFrame.loc[行索引名称或条件,列索引名称]
- iloc使用方法:
DataFrame.iloc[行索引名称,列索引名称]
- 使用loc和iloc实现单列切片
dishes_name1 = detail.loc[:,'dishes_name']
print('使用loc提取dishes_name列的size为:', dishes_name1.size)dishes_name2 = detail.iloc[:,3]
print('使用iloc提取第3列的size为:', dishes_name2.size)
使用loc提取dishes_name列的size为: 2779
使用iloc提取第3列的size为: 2779
- 使用loc、iloc实现多列切片
orderDish1 = detail.loc[:,['order_id','dishes_name']]
print('使用loc提取order_id和dishes_name列的size为:', orderDish1.size)orderDish2 = detail.iloc[:,[1,3]]
print('使用iloc提取第1和第3列的size为:', orderDish2.size)
使用loc提取order_id和dishes_name列的size为: 5558
使用iloc提取第1和第3列的size为: 5558
- 使用loc、iloc实现花式切片
print('列名为order_id和dishes_name的行名为3的数据为:\n',detail.loc[3,['order_id','dishes_name']])
print('列名为order_id和dishes_name行名为2,3,4,5,6的数据为:\n',detail.loc[2:6,['order_id','dishes_name']])
print('列位置为1和3行位置为3的数据为:\n',detail.iloc[3,[1,3]])
print('列位置为1和3行位置为2,3,4,5,6的数据为:\n',detail.iloc[2:7,[1,3]])
列名为order_id和dishes_name的行名为3的数据为:order_id 417
dishes_name 芝麻烤紫菜
Name: 3, dtype: object
列名为order_id和dishes_name行名为2,3,4,5,6的数据为:order_id dishes_name
2 417 大蒜苋菜
3 417 芝麻烤紫菜
4 417 蒜香包
5 301 白斩鸡
6 301 香烤牛排\r\n
列位置为1和3行位置为3的数据为:order_id 417
logicprn_name NA
Name: 3, dtype: object
列位置为1和3行位置为2,3,4,5,6的数据为:order_id logicprn_name
2 417 NA
3 417 NA
4 417 NA
5 301 NA
6 301 NA
- 使用loc和iloc实现条件切片
print('detail中order_id为458的dishes_name为:\n',detail.loc[detail['order_id']=='458',['order_id','dishes_name']])
print('detail中order_id为458的第1,5列数据为:\n',detail.iloc[detail['order_id']=='458',[1,5]])
detail中order_id为458的dishes_name为:order_id dishes_name
145 458 蒜香辣花甲
146 458 剁椒鱼头
147 458 凉拌蒜蓉西兰花
148 458 木须豌豆
149 458 辣炒鱿鱼
150 458 酸辣藕丁
151 458 炝炒大白菜
152 458 香菇鸡肉粥
153 458 干锅田鸡
154 458 桂圆枸杞鸽子汤
155 458 五香酱驴肉\r\n\r\n\r\n
156 458 路易拉菲红酒干红
157 458 避风塘炒蟹
158 458 白饭/大碗
NotImplementedError: iLocation based boolean indexing on an integer type is not available
- 使用iloc实现条件切片
print('detail中order_id为458的第1,5列数据为:\n',detail.iloc[(detail['order_id']=='458').values,[1,5]])
detail中order_id为458的第1,5列数据为:order_id dishes_name
145 458 蒜香辣花甲
146 458 剁椒鱼头
147 458 凉拌蒜蓉西兰花
148 458 木须豌豆
149 458 辣炒鱿鱼
150 458 酸辣藕丁
151 458 炝炒大白菜
152 458 香菇鸡肉粥
153 458 干锅田鸡
154 458 桂圆枸杞鸽子汤
155 458 五香酱驴肉\r\n\r\n\r\n
156 458 路易拉菲红酒干红
157 458 避风塘炒蟹
158 458 白饭/大碗
切片方法之ix
- ix使用方法:
DataFrame.ix[行索引的名称或位置或条件,列索引名称或位置]
print('列名为dishes_name行名为2,3,4,5,6的数据为:\n',detail.loc[2:6,'dishes_name'])
print('列位置为5,行位置为2至6的数据为:\n',detail.iloc[2:6,5])
print('列位置为5行名为2至6的数据为:', '\n',detail.ix[2:6,5])
列名为dishes_name行名为2,3,4,5,6的数据为:2 大蒜苋菜
3 芝麻烤紫菜
4 蒜香包
5 白斩鸡
6 香烤牛排\r\n
Name: dishes_name, dtype: object
列位置为5,行位置为2至6的数据为:2 大蒜苋菜
3 芝麻烤紫菜
4 蒜香包
5 白斩鸡
Name: dishes_name, dtype: object
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-40-a0f653049307> in <module>1 print('列名为dishes_name行名为2,3,4,5,6的数据为:\n',detail.loc[2:6,'dishes_name'])2 print('列位置为5,行位置为2至6的数据为:\n',detail.iloc[2:6,5])
----> 3 print('列位置为5行名为2至6的数据为:', '\n',detail.ix[2:6,5])D:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)5272 if self._info_axis._can_hold_identifiers_and_holds_name(name):5273 return self[name]
-> 5274 return object.__getattribute__(self, name)5275 5276 def __setattr__(self, name: str, value) -> None:AttributeError: 'DataFrame' object has no attribute 'ix'
- 问题:ix使用报错,因现在版本不适用ix
更改DataFrame中的数据
#将order_id为458的,变换为45800
detail.loc[detail['order_id']=='458','order_id'] = '45800'
print('更改后detail中order_id为458的order_id为:\n',detail.loc[detail['order_id']=='458','order_id'])
print('更改后detail中order_id为45800的order_id为:\n',detail.loc[detail['order_id']=='45800','order_id'])
更改后detail中order_id为458的order_id为:Series([], Name: order_id, dtype: object)
更改后detail中order_id为45800的order_id为:145 45800
146 45800
147 45800
148 45800
149 45800
150 45800
151 45800
152 45800
153 45800
154 45800
155 45800
156 45800
157 45800
158 45800
Name: order_id, dtype: object
为DataFrame增添数据
- 新增非定值
detail['payment'] = detail['counts'].astype(float)*detail['amounts'].astype(float)
print('detail新增列payment的前五行为:','\n',detail['payment'].head())
detail新增列payment的前五行为: 0 49.0
1 48.0
2 30.0
3 25.0
4 13.0
Name: payment, dtype: float64
- 新增定值
detail['pay_way'] = '现金支付'
print('detail新增列pay_way的前五行为:','\n',detail['pay_way'].head())
detail新增列pay_way的前五行为: 0 现金支付
1 现金支付
2 现金支付
3 现金支付
4 现金支付
Name: pay_way, dtype: object
删除某行或某列数据
- 语法:
DataFrame.drop(labels,axis=0,level=None,inplace=False,errors='raise')
drop方法的重要参数及其说明
参数名称 | 说明 |
---|---|
labels | 接收string或array。代表删除的行或列的标签。无默认 |
axis | 接收0或1.代表操作的轴向。默认为0 |
level | 接收int或者索引名。代表标签梭子啊级别。默认为None |
inplace | 接收boolean。代表操作是否对原数组生效。默认为False |
- 删除一列
print('删除pay_way前deatil的列索引为:','\n',detail.columns)
detail.drop(labels = 'pay_way',axis = 1,inplace = True)
print('删除pay_way后detail的列索引为:','\n',detail.columns)
删除pay_way前deatil的列索引为: Index(['detail_id', 'order_id', 'dishes_id', 'logicprn_name','parent_class_name', 'dishes_name', 'itemis_add', 'counts', 'amounts','cost', 'place_order_time', 'discount_amt', 'discount_reason','kick_back', 'add_inprice', 'add_info', 'bar_code', 'picture_file','emp_id', 'payment', 'pay_way'],dtype='object')
删除pay_way后detail的列索引为: Index(['detail_id', 'order_id', 'dishes_id', 'logicprn_name','parent_class_name', 'dishes_name', 'itemis_add', 'counts', 'amounts','cost', 'place_order_time', 'discount_amt', 'discount_reason','kick_back', 'add_inprice', 'add_info', 'bar_code', 'picture_file','emp_id', 'payment'],dtype='object')
- 删除多列
print('删除1-10行前detail的长度为:',len(detail))
detail.drop(labels = range(1,11),axis = 0,inplace = True)
print('删除1-10行后detail的列索引为:',len(detail))
删除1-10行前detail的长度为: 2779
删除1-10行后detail的列索引为: 2769
描述分析DataFrame数据
数值型特征的描述性统计
Numpy中的描述性统计函数
函数名称 | 说明 | 函数名称 | 说明 |
---|---|---|---|
np.min | 最小值 | np.max | 最大值 |
np.mean | 均值 | np.ptp | 极差 |
np.median | 中位数 | np.std | 标准差 |
np.var | 方差 | np.cov | 协方差 |
- 计算平均价格
import numpy as np
print('订单详情表中amount(价格)的平均值为:', np.mean(detail['amounts'].astype(float)))
订单详情表中amount(价格)的平均值为: 45.343084145901045
- 实现销量和价格的协方差矩阵计算
print('订单详情表中amount(价格)的平均值为:', detail['amounts'].astype(float).mean())
订单详情表中amount(价格)的平均值为: 45.343084145901045
- 描述性统计
print('订单详情表counts和amounts两列的描述性统计为:\n',detail[['counts','amounts']].describe())
订单详情表counts和amounts两列的描述性统计为:counts amounts
count 2769 2769
unique 9 55
top 1 35
freq 2628 239
类别型数据的描述性统计
pandas描述性统计方法
函数名称 | 说明 | 函数名称 | 说明 |
---|---|---|---|
min | 最小值 | max | 最大值 |
mean | 均值 | ptp | 极差 |
median | 中位数 | std | 标准差 |
var | 方差 | cov | 协方差 |
sem | 标准误差 | mode | 众数 |
skew | 样本偏度 | kurt | 样本峰值 |
quantile | 四分位数 | count | 非空值数目 |
describe | 描述统计 | mad | 平均绝对离差 |
- 菜品频数统计
print('订单详情表dishes_name频数统计结果前10为:\n',detail['dishes_name'].value_counts()[0:10])
订单详情表dishes_name频数统计结果前10为:白饭/大碗 91
凉拌菠菜 77
谷稻小庄 72
麻辣小龙虾 65
白饭/小碗 60
五色糯米饭(七色) 58
焖猪手 55
芝士烩波士顿龙虾 55
辣炒鱿鱼 53
水煮鱼 47
Name: dishes_name, dtype: int64
- 将object数据强制转化为category
detail['dishes_name'] = detail['dishes_name'].astype('category')
print('订单信息表dishes_name列转变数据类型后为:',detail['dishes_name'].dtypes)
订单信息表dishes_name列转变数据类型后为: category
- category类型特征的描述性统计
print('订单信息表dishes_name的描述统计结果为:\n',detail['dishes_name'].describe())
订单信息表dishes_name的描述统计结果为:count 2769
unique 154
top 白饭/大碗
freq 91
Name: dishes_name, dtype: object
任务实现
- 查看餐饮数据的大小和维度
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
order = pd.read_table('./data/meal_order_info.csv',sep = ',',encoding = 'gbk')
user = pd.read_excel('./data/users.xlsx')
print('订单详情表的维度为:', detail.ndim)
print('订单信息表的维度为:', order.ndim)
print('客户信息表的维度为:', user.ndim)print('订单详情表的形状为:', detail.shape)
print('订单信息表的形状为:', order.shape)
print('客户信息表的形状为:', user.shape)print('订单详情表的元素个数为:', detail.size)
print('订单信息表的元素个数为:', order.size)
print('客户信息表的元素个数为:', user.size)
订单详情表的维度为: 2
订单信息表的维度为: 2
客户信息表的维度为:2
订单详情表的形状为: (2779, 19)
订单信息表的形状为: (945, 21)
客户信息表的形状为: (734, 37)
订单详情表的元素个数为: 52801
订单信息表的元素个数为: 19845
客户信息表的元素个数为:27158
- 统计餐饮菜品销售情况
print('订单详情表counts和amounts两列的描述性统计为:\n',detail.loc[:, ['counts','amounts']].describe())
detail['order_id'] = detail['order_id'].astype('category')
detail['dishes_name'] = detail['dishes_name'].astype('category')
print('''订单信息表order_id(订单编号)与dishes_name(菜品名称)的描述性统计结果为:''', '\n',detail[['order_id','dishes_name']].describe())
订单详情表counts和amounts两列的描述性统计为:counts amounts
count 2779 2779
unique 9 55
top 1 35
freq 2638 239
订单信息表order_id(订单编号)与dishes_name(菜品名称)的描述性统计结果为: order_id dishes_name
count 2779 2779
unique 278 154
top 392 白饭/大碗
freq 24 92
- 剔除全为空值或者所有元素取值相同的列–定义一个函数去除全为空值的列和标准差为0的列
def dropNullStd(data):beforelen = data.shape[1]colisNull = data.describe().loc['count'] == 0for i in range(len(colisNull)):if colisNull[i]:data.drop(colisNull.index[i],axis = 1,inplace =True)stdisZero = data.describe().loc['std'] == 0for i in range(len(stdisZero)):if stdisZero[i]:data.drop(stdisZero.index[i],axis = 1,inplace =True)afterlen = data.shape[1]print('去除的列的数目为:',beforelen-afterlen)print('去除后数据的形状为:',data.shape)dropNullStd(order)
去除的列的数目为: 7
去除后数据的形状为: (945, 14)
转换与处理时间系列数据
转换字符串时间为标准时间
pandas时间相关的类
类名称 | 说明 |
---|---|
Timestamp | 最基础的时间类。表示某个时间点。绝大多数的场景中的时间数据都是Timestamp形式 |
Period | 表示单个时间跨度,或者某个时间段,例如某一天、某一小时等 |
Timedelta | 表示不同单位的时间,例如1d、1.5h、3min、4s等,而非具体的某个时间段 |
DatetimeIndex | 一组Timestamp构成的Index,可以用来最为Series或者DataFrame的索引 |
PeriodtimeIndex | 一组Period构成的Index,可以用来最为Series或者DataFrame的索引 |
TimedeltaIndex | 一组Timedelta构成的Index,可以用来最为Series或者DataFrame的索引 |
DatetimeIndex与PeriodIndex函数及其参数说明
参数名称 | 说明 |
---|---|
data | 接收array。表示DatetimeIndex的值。无默认 |
freq | 接收string。表示时间的间隔频率。无默认 |
start | 接收string。表示生成规则时间数据的起始点。无默认 |
periods | 表示需要生成的周期数目。无默认 |
end | 接收string。表示生成规则时间数据的终结点。无默认 |
tz | 接收timezone。表示数据的时区。默认为None |
name | 接收int、string。默认为空。指定DatetimeIndex的名字 |
- 转换字符串时间为标准时间
import pandas as pd
order = pd.read_table('./data/meal_order_info.csv',sep = ',',encoding = 'gbk')
print('进行转换前订单信息表lock_time的类型为:', order['lock_time'].dtypes)
order['lock_time'] = pd.to_datetime(order['lock_time'])
print('进行转换后订单信息表lock_time的类型为:', order['lock_time'].dtypes)
进行转换前订单信息表lock_time的类型为: object
进行转换后订单信息表lock_time的类型为: datetime64[ns]
- Timestamp的最小时间和最大时间
print('最小时间为:', pd.Timestamp.min)
print('最大时间为:', pd.Timestamp.max)
最小时间为: 1677-09-21 00:12:43.145225
最大时间为: 2262-04-11 23:47:16.854775807
- 时间字符串转换为DatetimeIndex和PeriodIndex
dateIndex = pd.DatetimeIndex(order['lock_time'])
print('转换为DatetimeIndex后数据的类型为:\n',type(dateIndex))periodIndex = pd.PeriodIndex(order['lock_time'],freq = 'S')
print('转换为DatetimeIndex后数据的类型为:\n',type(periodIndex))
转换为DatetimeIndex后数据的类型为:<class 'pandas.core.indexes.datetimes.DatetimeIndex'>
转换为DatetimeIndex后数据的类型为:<class 'pandas.core.indexes.period.PeriodIndex'>
提取时间序列数据信息
Timestamp类常用属性及说明
属性名称 | 说明 | 属性名称 | 说明 |
---|---|---|---|
year | 年 | week | 一年中第几周 |
month | 月 | quarter | 季节 |
day | 日 | weekofyear | 一年中第几周 |
hours | 小时 | dayofyear | 一年中的第几天 |
minite | 分钟 | dayofweek | 一周第几天 |
second | 秒 | weekday | 一周第几天 |
date | 日期 | day_name | 星期名称 |
time | 时间 | is_leap_year | 是否闰年 |
- 提取datetime数据中的时间序列
year1 = [i.year for i in order['lock_time']]
print('lock_time中的年份数据前5个为:',year1[:5])
month1 = [i.month for i in order['lock_time']]
print('lock_time中的月份数据前5个为:',month1[:5])
day1 = [i.day for i in order['lock_time']]
print('lock_time中的日期数据前5个为:',day1[:5])
weekday1 = [i.weekday for i in order['lock_time']]
print('lock_time中的星期名称数据前5个为:',weekday1[:5])
lock_time中的年份数据前5个为: [2016, 2016, 2016, 2016, 2016]
lock_time中的月份数据前5个为: [8, 8, 8, 8, 8]
lock_time中的日期数据前5个为: [1, 1, 1, 1, 1]
lock_time中的星期名称数据前5个为: [<built-in method weekday of Timestamp object at 0x0000019302176348>, <built-in method weekday of Timestamp object at 0x00000193021763C8>, <built-in method weekday of Timestamp object at 0x0000019302A26248>, <built-in method weekday of Timestamp object at 0x0000019302A260C8>, <built-in method weekday of Timestamp object at 0x0000019302A26148>]
- 提取DatetimeIndex和PeriodIndex中的数据
week_dict = {0.0:"Monday",1.0:"Tuesday",2.0:"Wednesday",3.0:"Thursday",4.0:"Friday",5.0:"Saturday",6.0:"Sunday"}
print('dateIndex中的星期名称数据前5个为:\n',[week_dict[i] for i in dateIndex.weekday[:5]])
print('periodIndex中的星期标号数据前5个为:',periodIndex.weekday[:5])
dateIndex中的星期名称数据前5个为:['Monday', 'Monday', 'Monday', 'Monday', 'Monday']
periodIndex中的星期标号数据前5个为: Int64Index([0, 0, 0, 0, 0], dtype='int64', name='lock_time')
加减时间数据
Timedelta类周期名称、对应单位及其说明
周期名称 | 单位 | 说明 |
---|---|---|
weeks | 无 | 星期 |
days | D | 天 |
hours | h | 小时 |
minutes | m | 分 |
seconds | s | 秒 |
milliseconds | ms | 毫秒 |
microseconds | us | 微秒 |
nanoseconds | ns | 纳秒 |
- 使用Timedelta实现时间数据的加运算
# 将lock_time数据向后平移一天
time1 = order['lock_time']+pd.Timedelta(days = 1)
print('lock_time在加上一天前前5行数据为:\n',order['lock_time'][:5])
print('lock_time在加上一天前前5行数据为:\n',time1[:5])
lock_time在加上一天前前5行数据为:0 2016-08-01 11:11:46
1 2016-08-01 11:31:55
2 2016-08-01 12:54:37
3 2016-08-01 13:08:20
4 2016-08-01 13:07:16
Name: lock_time, dtype: datetime64[ns]
lock_time在加上一天前前5行数据为:0 2016-08-02 11:11:46
1 2016-08-02 11:31:55
2 2016-08-02 12:54:37
3 2016-08-02 13:08:20
4 2016-08-02 13:07:16
Name: lock_time, dtype: datetime64[ns]
- 使用Timedelta实现时间数据的减运算
timeDelta = order['lock_time'] - pd.to_datetime('2017-1-1')
print('lock_time减去2017年1月1日0点0时0分后的数据:\n',timeDelta[:5])
print('lock_time减去time1后的数据类型为:',timeDelta.dtypes)
lock_time减去2017年1月1日0点0时0分后的数据:0 -153 days +11:11:46
1 -153 days +11:31:55
2 -153 days +12:54:37
3 -153 days +13:08:20
4 -153 days +13:07:16
Name: lock_time, dtype: timedelta64[ns]
lock_time减去time1后的数据类型为: timedelta64[ns]
任务实现
- 时间字符串转化为标准时间格式–订单信息表时间数据转换
在订单信息表中存在两个时间特征,use_start_time和lock_time,分别表示了开始的时间和结算订单的时间。需要将这两个特征转化为标准的时间格式
import pandas as pd
order = pd.read_table('./data/meal_order_info.csv',sep = ',',encoding = 'gbk')
order['use_start_time'] = pd.to_datetime(order['use_start_time'])
order['lock_time'] = pd.to_datetime(order['lock_time'])
print('进行转换后订单信息表use_start_time和lock_time的类型为:\n', order[['use_start_time','lock_time']].dtypes)
进行转换后订单信息表use_start_time和lock_time的类型为:use_start_time datetime64[ns]
lock_time datetime64[ns]
dtype: object
- 提取菜品数据中的年月日和信息特征
use_start_time和lock_time两个特征中的时间信息基本一直,故只需要提取其中一个特征的时间信息即可。
year = [i.year for i in order['lock_time']]## 提取年份信息
month = [i.month for i in order['lock_time']]## 提取月份信息
day = [i.day for i in order['lock_time']]## 提取日期信息
week = [i.week for i in order['lock_time']]## 提取周信息
weekday = [i.weekday() for i in order['lock_time']]##提取星期信息
## 提取星期名称信息
weekname = [i.weekday() for i in order['lock_time']]
week_dict = {0.0:"Monday",1.0:"Tuesday",2.0:"Wednesday",3.0:"Thursday",4.0:"Friday",5.0:"Saturday",6.0:"Sunday"}
print('订单详情表中的前5条数据的年份信息为:',year[:5])
print('订单详情表中的前5条数据的月份信息为:',month[:5])
print('订单详情表中的前5条数据的日期信息为:',day[:5])
print('订单详情表中的前5条数据的周信息为:',week[:5])
print('订单详情表中的前5条数据的星期信息为:',weekday[:5])
print('订单详情表中的前5条数据的星期名称信息为:',[week_dict[i] for i in weekname[:5]])
订单详情表中的前5条数据的年份信息为: [2016, 2016, 2016, 2016, 2016]
订单详情表中的前5条数据的月份信息为: [8, 8, 8, 8, 8]
订单详情表中的前5条数据的日期信息为: [1, 1, 1, 1, 1]
订单详情表中的前5条数据的周信息为: [31, 31, 31, 31, 31]
订单详情表中的前5条数据的星期信息为: [0, 0, 0, 0, 0]
订单详情表中的前5条数据的星期名称信息为: ['Monday', 'Monday', 'Monday', 'Monday', 'Monday']
- 查看订单时间表时间统计信息
通过求取最早时间和最晚时间的差值来计算整体订单的时间跨度,还能够将use_start_time和lock_time两个特征做加减运算,可以看出开始点餐至结束订单的时间。
timemin = order['lock_time'].min()
timemax = order['lock_time'].max()
print('订单最早的时间为:',timemin)
print('订单最晚的时间为:',timemax)
print('订单持续的时间为:',timemax-timemin)chekTime = order['lock_time'] - order['use_start_time']
print('平均点餐时间为:',chekTime.mean())
print('最小点餐时间为:',chekTime.min())
print('最大点餐时间为:',chekTime.max())
订单最早的时间为: 2016-08-01 11:11:46
订单最晚的时间为: 2016-08-31 21:56:12
订单持续的时间为: 30 days 10:44:26
平均点餐时间为: 0 days 01:12:10.326923
最小点餐时间为: -1 days +00:05:03
最大点餐时间为: 16 days 00:08:00
可以发现最短时间和最长时间均为异常值,开始时间不可能在结束订单时间之后,点餐时间也不可能持续16天,可以考虑对这部分数据做合适的处理
使用分组聚合进行组内计算
使用groupby方法拆分数据
- 语法:
DataFrame.groupby(by=None,axis=0,level=None,as_index=True,sort=True,group_keys=True,squeeze=False,**kwargs)
groupby方法的参数及其说明
参数名称 | 说明 |
---|---|
by | 接收list、string、mapping或generator。用于确定分组的依据。如果传入的时一个函数,则对索引进行计算并分组;如果传入的时一个字典或者Series,则字典或者Series的值用来作为分组依据;如果传入一个NumPy数组,则于数据的元素作为分组依据;如果传入的时字符串或者字符串列表,则使用这些字符串所代表的字段作为分组依据。无默认 |
axis | 接收int。表示操作的轴向,魔派任对列进行操作。默认为0 |
level | 接收int或者索引名。代表标签所在级别。默认为None |
as_index | 接收boolean。表示聚合后的聚合标签是否以DataFrame索引形式输出。默认为True |
sort | 接收boolean。表示是否对分组依据、分组标签进行排序。默认为True |
group_keys | 接收boolean。表示是否显示分组标签的名称。默认为True |
squeeze | 接收boolean。表示是否在允许的情况下返回数据进行降维。默认为False |
groupby常用描述性统计方法及说明
方法名称 | 说明 |
---|---|
count | 计算分组的数目,包括缺失值 |
head | 返回每组的前n个值 |
max | 返回每组最大值 |
mean | 返回每组均值 |
median | 返回每组中位数 |
cumcount | 对每个分组中的组员进行标记,0~n-1 |
size | 返回每组的大小 |
min | 返回每组最小值 |
std | 返回每组的标准差 |
sum | 返回每组的和 |
- 对菜品订单详情表依据订单编号进行分组
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
detailGroup = detail[['order_id','counts','amounts']].astype(float).groupby(by = 'order_id')
print('分组后的订单详情表为:',detailGroup)
分组后的订单详情表为: <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000022A64FC0488>
- groupby求均值、标准差、中位数
print('订单详情表分组后前5组每组的均值为:\n', detailGroup.mean().head())
print('订单详情表分组后前5组每组的标准差为:\n', detailGroup.std().head())
print('订单详情表分组后前5组每组的大小为:','\n', detailGroup.size().head())
订单详情表分组后前5组每组的均值为:counts amounts
order_id
137.0 1.500000 32.333333
165.0 1.166667 52.944444
166.0 1.400000 48.200000
171.0 1.428571 36.285714
177.0 1.000000 34.250000
订单详情表分组后前5组每组的标准差为:counts amounts
order_id
137.0 1.224745 35.200379
165.0 0.383482 52.193613
166.0 0.547723 41.829415
171.0 1.133893 19.267540
177.0 0.000000 15.019432
订单详情表分组后前5组每组的大小为: order_id
137.0 6
165.0 18
166.0 5
171.0 7
177.0 4
dtype: int64
使用agg方法聚合数据
- 语法:
DataFrame.agg(func,axis=0,*args,**kwargs) DataFrame.aggregate(func,axis=0,*args,**kwargs)
agg和aggregate函数的参数及其说明
参数名称 | 说明 |
---|---|
func | 接收list、dict、function。表示应用与每行或每列的函数。无默认 |
axis | 接收0或1。表示操作的轴向。默认为0 |
- 使用agg求出当前数据对应的统计量
print('订单详情表的菜品销量与售价的和与均值为:\n',detail[['counts','amounts']].astype(float).agg([np.sum,np.mean]))
订单详情表的菜品销量与售价的和与均值为:counts amounts
sum 3088.000000 125992.000000
mean 1.111191 45.337172
- 使用agg分别求字段的不同统计量
detail['counts']=detail['counts'].astype(float)
detail['amounts']=detail['amounts'].astype(float)
print('订单详情表的菜品销量总和与售价的均值为:\n',detail.agg({'counts':np.sum,'amounts':np.mean}))
订单详情表的菜品销量总和与售价的均值为:counts 3088.000000
amounts 45.337172
dtype: float64
- 使用agg方法求不同字段的不同数目统计量
print('菜品订单详情表的菜品销量总和与售价的总和与均值为:\n',detail.agg({'counts':np.sum,'amounts':[np.mean,np.sum]}))
菜品订单详情表的菜品销量总和与售价的总和与均值为:counts amounts
mean NaN 45.337172
sum 3088.0 125992.000000
- 在agg方法中使用自定义函数
#自定义函数求两倍的和
def DoubleSum(data):s = data.sum()*2return s
print('菜品订单详情表的菜品销量两倍总和为:','\n',detail.agg({'counts':DoubleSum},axis = 0))
菜品订单详情表的菜品销量两倍总和为: counts 6176.0
dtype: float64
- agg方法中使用的自定义函数含Numpy中的函数
#自定义函数求两倍的和
def DoubleSum1(data):s = np.sum(data)*2return s
print('订单详情表的菜品销量两倍总和为:\n',detail.agg({'counts':DoubleSum1},axis = 0).head())print('订单详情表的菜品销量与售价的和的两倍为:\n',detail[['counts','amounts']].agg(DoubleSum1))
订单详情表的菜品销量两倍总和为:counts
0 2.0
1 2.0
2 2.0
3 2.0
4 2.0
订单详情表的菜品销量与售价的和的两倍为:counts 6176.0
amounts 251984.0
dtype: float64
- 使用agg方法做简单的聚合
print('订单详情表分组后前3组每组的均值为:\n', detailGroup.agg(np.mean).head(3))print('订单详情表分组后前3组每组的标准差为:\n', detailGroup.agg(np.std).head(3))
订单详情表分组后前3组每组的均值为:counts amounts
order_id
137.0 1.500000 32.333333
165.0 1.166667 52.944444
166.0 1.400000 48.200000
订单详情表分组后前3组每组的标准差为:counts amounts
order_id
137.0 1.224745 35.200379
165.0 0.383482 52.193613
166.0 0.547723 41.829415
- 使用agg方法对数据分组使用不同的聚合函数
print('订单详情分组前3组每组菜品总数和售价均值为:\n', detailGroup.agg({'counts':np.sum,'amounts':np.mean}).head(3))
订单详情分组前3组每组菜品总数和售价均值为:counts amounts
order_id
137.0 9.0 32.333333
165.0 21.0 52.944444
166.0 7.0 48.200000
使用apply方法聚合数据
- apply方法类似于agg方法,能够将函数应用同于每一列。不同为agg方法传入的函数只能作用于整个DataFrame或者Series,而无法像agg一样能够对不同字段应用不同函数来获取不同结果。语法:
DataFrame.apply(func,axis=0,broadcast=False,raw=False,reduce=None,args=(),**kwds)
apply方法的重要参数及其说明
参数名称 | 说明 |
---|---|
func | 接收functions。表示应用与每行或每列的函数。无默认 |
axis | 接收0或1。表示操作的轴向。默认为0 |
broadcast | 接收boolean。表示是否进行广播。默认为False |
raw | 接收boolean。表示是否直接将ndarray对象传递给函数。默认为False |
reduce | 接收boolean或者None。表示返回值的格式。默认为None |
- apply方法的基本用法
print('订单详情表的菜品销量与售价的均值为:\n',detail[['counts','amounts']].apply(np.mean))
订单详情表的菜品销量与售价的均值为:counts 1.111191
amounts 45.337172
dtype: float64
- 使用apply方法进行聚合操作
print('订单详情表分组后前3组每组的均值为:','\n', detailGroup.apply(np.mean).head(3))
print('订单详情表分组后前3组每组的标准差为:','\n', detailGroup.apply(np.std).head(3))
订单详情表分组后前3组每组的均值为: order_id counts amounts
order_id
137.0 137.0 1.500000 32.333333
165.0 165.0 1.166667 52.944444
166.0 166.0 1.400000 48.200000
订单详情表分组后前3组每组的标准差为: order_id counts amounts
order_id
137.0 0.0 1.118034 32.133402
165.0 0.0 0.372678 50.723074
166.0 0.0 0.489898 37.413367
使用transform方法聚合数据
- 使用transform方法将销量和售价翻倍
print('订单详情表的菜品销量与售价的两倍为:\n',detail[['counts','amounts']].transform(lambda x:x*2).head(4))
订单详情表的菜品销量与售价的两倍为:counts amounts
0 2.0 98.0
1 2.0 96.0
2 2.0 60.0
3 2.0 50.0
- 使用transform实现组内离差标准化
print('订单详情表分组后实现组内离差标准化后前五行为:\n', detailGroup.transform(lambda x:(x.mean()-x.min())/(x.max()-x.min())).head())
任务实现
- 按照时间对菜品订单详情表进行拆分
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:1234@127.0.0.1:\
3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
detail['place_order_time'] = pd.to_datetime(detail['place_order_time'])
detail['date'] = [i.date() for i in detail['place_order_time']]
detail[['counts','amounts']] = detail[['counts','amounts']].astype(float)
detailGroup = detail[['date','counts','amounts']].groupby(by='date')
print('订单详情表前5组每组的数目为:\n',detailGroup.size().head())
订单详情表前5组每组的数目为:date
2016-08-01 217
2016-08-02 138
2016-08-03 157
2016-08-04 144
2016-08-05 193
dtype: int64
- 使用agg方法计算单日菜品销售的平均单价和售价中位数
dayMean = detailGroup.agg({'amounts':np.mean})
print('订单详情表前五组每日菜品均价为:\n',dayMean.head())dayMedian = detailGroup.agg({'amounts':np.median})
print('订单详情表前五组每日菜品售价中位数为:\n',dayMedian.head())
订单详情表前五组每日菜品均价为:amounts
date
2016-08-01 43.161290
2016-08-02 44.384058
2016-08-03 43.885350
2016-08-04 52.423611
2016-08-05 44.927461
订单详情表前五组每日菜品售价中位数为:amounts
date
2016-08-01 33.0
2016-08-02 35.0
2016-08-03 38.0
2016-08-04 39.0
2016-08-05 37.0
- 使用apply方法统计单日菜品销售数目
daySaleSum = detailGroup.apply(np.sum)['counts']
print('订单详情表前五组每日菜品售出数目为:\n',daySaleSum.head())
订单详情表前五组每日菜品售出数目为:date
2016-08-01 233.0
2016-08-02 151.0
2016-08-03 192.0
2016-08-04 169.0
2016-08-05 224.0
Name: counts, dtype: float64
创建透视表与交叉表
使用pivot_table函数创建透视表
- 语法:
pandas.pivot_table(data,values=None,index=None,columns=None,aggfunc='mean',fill_value=None,margins=False,dropna=True,margins_name='All')
pivot_table函数的常用参数及其说明
参数名称 | 说明 |
---|---|
data | 接收DataFrame。表示创建表的数据。无默认 |
values | 接收string。用于指定要聚合的数据字段名,默认使用全部数据。默认为None |
index | 接收string或list。表示行分组键。默认为None |
columns | 接收string或list。表示列分组键。默认为None |
aggfunc | 接收functions。表示聚合函数。默认为mean |
margins | 接收boolean。表示汇总(Total)功能的开关,设置为True后,结果集中会出现名为“All”的行和列。默认为True |
dropna | 接收boolean。表示是否删掉全为NaN的列。默认为False |
- 使用订单号作为透视表索引制作透视表
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:1234@\
127.0.0.1:3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
detail[['counts','amounts']]=detail[['counts','amounts']].astype(float)
detailPivot = pd.pivot_table(detail[['order_id','counts','amounts']],index = 'order_id')
print('以order_id作为分组键创建的订单透视表为:\n',detailPivot.head())
以order_id作为分组键创建的订单透视表为:amounts counts
order_id
1002 32.000 1.0000
1003 30.125 1.2500
1004 43.875 1.0625
1008 63.000 1.0000
1011 57.700 1.0000
- 修改聚合函数后的透视表
detailPivot1 = pd.pivot_table(detail[['order_id','counts','amounts']],index = 'order_id',aggfunc = np.sum)
print('以order_id作为分组键创建的订单销量与售价总和透视表为:\n',detailPivot1.head())
以order_id作为分组键创建的订单销量与售价总和透视表为:amounts counts
order_id
1002 224.0 7.0
1003 241.0 10.0
1004 702.0 17.0
1008 315.0 5.0
1011 577.0 10.0
- 使用订单号和菜品名称作为索引的透视表
detailPivot2 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index = ['order_id','dishes_name'],aggfunc = np.sum)
print('以order_id和dishes_name作为分组键创建的订单\
销量与售价总和透视表为:\n',detailPivot2.head())
以order_id和dishes_name作为分组键创建的订单销量与售价总和透视表为:amounts counts
order_id dishes_name
1002 凉拌菠菜 27.0 1.0南瓜枸杞小饼干 19.0 1.0焖猪手 58.0 1.0独家薄荷鲜虾牛肉卷\r\n\r\n\r\n 45.0 1.0白胡椒胡萝卜羊肉汤 35.0 1.0
- 指定菜品名称为列分组键的透视表
detailPivot2 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index = 'order_id',columns = 'dishes_name',aggfunc = np.sum)
print('以order_id和dishes_name作为行列分组键创建的\
透视表前5行4列为:\n',detailPivot2.iloc[:5,:4])
以order_id和dishes_name作为行列分组键创建的透视表前5行4列为:amounts
dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒
order_id
1002 NaN NaN NaN NaN
1003 NaN NaN NaN NaN
1004 NaN NaN NaN NaN
1008 NaN NaN NaN NaN
1011 99.0 NaN NaN NaN
- 指定某些列制作透视表
detailPivot4 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index = 'order_id',values = 'counts',aggfunc = np.sum)
print('以order_id作为行分组键counts作为值创建的\
透视表前5行为:\n',detailPivot4.head())
以order_id作为行分组键counts作为值创建的透视表前5行为:counts
order_id
1002 7.0
1003 10.0
1004 17.0
1008 5.0
1011 10.0
- 对透视表中的缺失值进行填充
detailPivot5 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index = 'order_id',columns = 'dishes_name',aggfunc = np.sum,fill_value = 0)
print('空值填0后以order_id和dishes_name为行列分组键\
创建透视表前5行4列为:\n',detailPivot5.iloc[:5,:4])
空值填0后以order_id和dishes_name为行列分组键创建透视表前5行4列为:amounts
dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒
order_id
1002 0 0 0 0
1003 0 0 0 0
1004 0 0 0 0
1008 0 0 0 0
1011 99 0 0 0
- 在透视表中添加汇总数据
detailPivot6 = pd.pivot_table(detail[['order_id','dishes_name','counts','amounts']],index = 'order_id',columns = 'dishes_name',aggfunc = np.sum,fill_value = 0,margins = True)
print('添加margins后以order_id和dishes_name为分组键\
的透视表前5行后4列为:\n',detailPivot6.iloc[:5,-4:])
添加margins后以order_id和dishes_name为分组键的透视表前5行后4列为:counts
dishes_name 黄油曲奇饼干 黄花菜炒木耳 黑米恋上葡萄 All
order_id
1002 0 0 0 7.0
1003 0 0 0 10.0
1004 0 1 0 17.0
1008 0 0 0 5.0
1011 0 0 0 10.0
使用crosstab函数创建交叉表
- 语法:
pandas.crosstab(index,columns,values=None,rownames=None,colnames=None,aggfunc='mean',margins=False,dropna=True,normalize=False)
crosstab函数的常用参数及其说明
参数名称 | 说明 |
---|---|
index | 接收string或list。表示行索引键。无默认 |
columns | 接收string或list。表示列索引键。无默认 |
values | 接收array。表示聚合数据。默认为None |
rownames | 表示行分组键名。无默认 |
colnames | 表示列分组键名。无默认 |
aggfunc | 接收function。表示聚合函数。默认为mean |
margins | 接收boolean。默认为True。表示汇总(Total)功能的开关,设置为True后,结果集中会出现名为“All”的行和列。 |
dropna | 接收boolean。表示是否删掉全为NaN的列。默认为False |
normalize | 接收boolean。表示是否对值进行标准化。默认为False |
- 使用crosstab函数制作交叉表
detailCross = pd.crosstab(index=detail['order_id'],columns=detail['dishes_name'],values = detail['counts'],aggfunc = np.sum)
print('以order_id和dishes_name为分组键\
counts为值的透视表前5行5列为:\n',detailCross.iloc[:5,:5])
以order_id和dishes_name为分组键counts为值的透视表前5行5列为:dishes_name 42度海之蓝 北冰洋汽水 38度剑南春 50度古井贡酒 52度泸州老窖
order_id
1002 NaN NaN NaN NaN NaN
1003 NaN NaN NaN NaN NaN
1004 NaN NaN NaN NaN NaN
1008 NaN NaN NaN NaN NaN
1011 1.0 NaN NaN NaN NaN
任务实现
- 创建单日菜品成交总额与总数均价透视表
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:1234@\
127.0.0.1:3306/testdb?charset=utf8')
detail = pd.read_sql_table('meal_order_detail1',con = engine)
detail['place_order_time'] = pd.to_datetime(detail['place_order_time'])
detail['date'] = [i.date() for i in detail['place_order_time']]
PivotDetail = pd.pivot_table(detail[['date','dishes_name','counts','amounts']],index ='date',aggfunc = np.sum,margins = True)
print('订单详情表单日菜品成交总额与总数透视表前5行5列为:\n',PivotDetail.head())
订单详情表单日菜品成交总额与总数透视表前5行5列为:amounts counts
date
2016-08-01 9366.0 233.0
2016-08-02 6125.0 151.0
2016-08-03 6890.0 192.0
2016-08-04 7549.0 169.0
2016-08-05 8671.0 224.0
- 创建单个菜品单日成交总额透视表
CrossDetail = pd.crosstab(index=detail['date'],columns=detail['dishes_name'],values = detail['amounts'],aggfunc = np.sum,margins = True)
print('订单详情表单日单个菜品成交总额交叉表后5行5列为:\n',CrossDetail.iloc[-5:,-5:])
订单详情表单日单个菜品成交总额交叉表后5行5列为:dishes_name 黄尾袋鼠西拉子红葡萄酒 黄油曲奇饼干 黄花菜炒木耳 黑米恋上葡萄 All
date
2016-08-07 230.0 32.0 105.0 99.0 31306.0
2016-08-08 46.0 NaN NaN 33.0 6532.0
2016-08-09 138.0 NaN 35.0 99.0 7155.0
2016-08-10 46.0 NaN 70.0 33.0 10231.0
All 736.0 80.0 525.0 561.0 125992.0
python--pandas统计分析基础相关推荐
- 数据科学与python——Pandas统计分析基础(数据堆叠+数据清洗)
Pandas统计分析基础数据堆叠+数据清洗 一.合并数据:获取完整的数据集. 1.读取数据 2.将两个csv文件按照mete.csv文件的日期对齐 3.纵向合并数据data1与data2 4.使用dr ...
- 数据科学与python语言——Pandas统计分析基础(时间转换+聚合)
Pandas统计分析基础(时间转换+聚合) 实验要求一 实验二要求 全部代码 实验要求一 #M表的时间戳类型转为datetime data_Mete['TIMESTAMP']=pd.to_dateti ...
- Python—实训day7下—Pandas统计分析基础
1读写不同数据源的数据 1.1读写文本文件 1.1.1文件读取 文本文件(txt文件)是一种由若干行字符构成的计算机文件,它是一种典型的顺序文件.使用read_table来读取文本文件: pandas ...
- 数据科学库Python——Pandas使用基础
目录 Pandas使用基础 一.Series的使用基础 (1)通过pd.Series来创建数组 (2)pd.Series中改变index a.在pd.Series中传入index的具体参数值来指定索引 ...
- 【python与数据分析】Pandas统计分析基础
目录 前言 一.pandas常用数据类型 综述 1.一维数组(Series)与常用操作 (1) 通过列表创建Series (2)创建Series时指定索引 (3)Series位置和标签的使用 (4)通 ...
- Pandas 统计分析基础 笔记4 任务4.4 使用分组聚合进行组内计算
文章目录 pandas_任务4.4 使用分组聚合进行组内计算 4.4.1 使用groupby方法拆分数据 代码 4-51 对菜品订单详情表依据订单编号分组 代码 4-52 GroupBy 类求均值,标 ...
- Pandas 统计分析基础 笔记5 _任务4.5 创建透视表与交叉表
文章目录 pandas__任务4.5 创建透视表与交叉表 4.5 创建透视表与交叉表 代码4-67 使用订单号作为透视表索引制作透视表 代码 4-68 修改聚合函数后的透视表 代码 4-69 使用订单 ...
- 第四章 Pandas统计分析基础
文章目录 1:判断题 2:填空题 3:选择题 1:判断题 1:创建Series时如果指定了index,则只能用index访问数据 错误 2:创建DataFrame时会自动加上索引,且全部列会被有 ...
- Pandas 统计分析基础 笔记2 任务4.2 掌握DataFrame的常用操作
文章目录 pandas_任务4.2 掌握DataFrame的常用操作 代码4-12 订单详情表的4个基本属性 4-13 size,ndim,shape属性的使用 4-14 使用T属性进行转置 4-15 ...
- Pandas统计分析基础(5):DataFrame的合并(内含大量代码可供练习)
✅作者简介:大家好我是Xlong,一枚正在学习COMSOL.Python的工科研究僧
最新文章
- max7456 C语言,用于MAX7456随屏显示器SPI
- CVPR 2020丨基于点云的3D物体检测新框架
- python在windows安装paramiko模块
- easyui的validatebox重写自定义验证规则的几个实例
- error: expected expression before ‘;’ token的问题
- python端口与c的区别_Python和C区别该如何理解?如何适应这种区别?
- swing tree 去掉双击默认展开 关闭_如何保护自己的电脑,关闭危险端口(一)
- Host-Only(仅主机模式)
- 前端- 不用React 而使用 Vue,这么做对吗?
- php备份网站程序,使用PHP备份整个网站
- Unity——Animation
- c语言 虚拟示波器软件下载,虚拟示波器软件(示波器工具)V3.1 官方版
- 网页底部小鱼游动特效
- 抖音如何开通直播教程
- Nginx的proxy_pass和fastcgi_pass
- 数字水印常见攻击类型汇总,噪声,缩放,旋转,剪切(附matlab代码)
- 设计师想法_设计师阻止了想法一旦出现时该怎么办
- 分享同城小程序怎么做_同城跑腿小程序开发基本功能
- 结合工作详解PDCA实践
- oracle移花接木,移植苹果,Windows PC上安装MacOS
热门文章
- 阿里云SLB最佳实践
- 职场必备技之二阶堂红丸
- 利用Python的全国旅游景点数据分析案例(新手)
- 【图像加密】基于混沌系统进行灰度图像加密附Matlab代码
- mysql日志文件名字_MySQL各类日志文件相关变量介绍
- 卷积码树状图怎么画_第八讲卷积码详解.ppt
- 练习:银行复利计算(用 for 循环解一道初中小题)
- 全球与中国2,5-二甲基吡啶试剂市场现状及未来发展趋势
- html简单个人网页制作 HTML5+CSS大作业——程序员个人简历设计(5页)
- linux centos7 在线和离线安装字体