第四章 pandas统计分析基础
4.1读/写不同数据源的数据
4.1.1读/写数据库数据
1、数据库数据读取
import MySQLdb
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine("mysql+pymysql://root:[email protected]/testdb?charset=utf8mb4")
session = sessionmaker(bind=engine)
print(engine)
print(session)
Engine(mysql+pymysql://root:***@127.0.0.1/testdb?charset=utf8mb4)
sessionmaker(class_='Session', bind=Engine(mysql+pymysql://root:***@127.0.0.1/testdb?charset=utf8mb4), autoflush=True, autocommit=False, expire_on_commit=True)
#使用read_sql_table、read_sql_query、read_sql函数读取数据库数据
import pandas as pd
formlist=pd.read_sql_query('show tables',con=engine)
print('testdb数据库数据表清单为:','\n',formlist)
testdb数据库数据表清单为:
Tables_in_testdb
0 meal_order_detail1
1 meal_order_detail2
2 meal_order_detail3
3 test1
C:\Users\ljy15\AppData\Roaming\Python\Python37\site-packages\pymysql\cursors.py:170: Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'VARIABLE_VALUE' at row 484")
result = self._query(query)
# 使用read_sql_table读取订单详情表
detail1=pd.read_sql_table('meal_order_detail1',con=engine)
print('使用read_sql_table读取订单详情表的长度为',len(detail1))
使用read_sql_table读取订单详情表的长度为 2779
#使用read_sql读取订单详情表
detail2=pd.read_sql('select * from meal_order_detail2',con=engine)
print('使用read_sql函数+sql语句读取订单详情表的长度为',len(detail2))
detail3=pd.read_sql('select * from meal_order_detail3',con=engine)
print('使用read_sql函数+sql语句读取订单详情表的长度为',len(detail3))
使用read_sql函数+sql语句读取订单详情表的长度为 7294
使用read_sql函数+sql语句读取订单详情表的长度为 3611
2、数据库数据存储
注意
在进行这步操作前,记得直接将数据库的编码改为:utf8mb4_general_ci,同时Python代码里,连接数据库时用
charset=“utf8mb4”,并且将test1表的编码设为一致,在cmd端进入对应数据库中进行设置 alter table test1 convert to character set utf8mb4;
#使用to_sql方法写入数据
#使用to_sql存储orderData
detail1.to_sql('test1',con=engine,index=False,if_exists='replace')#test1代表写入的数据库表名,con接收数据库连接,index表示是否将行索引作为数据传入数据库,
#if_exists接收fail,replace,append。fail表示如果表名存在,则不执行写入操作,replace表示如果存在,则将原数据库表删除,再重新创建;append则表示原数据库表的基础上追加数据,默认为fail
#使用read_sql读取test表
formlist1=pd.read_sql_query('show tables',con=engine)
print(formlist1)
Tables_in_testdb
0 meal_order_detail1
1 meal_order_detail2
2 meal_order_detail3
3 test1
4.1.2 读/写文本文件
1、文本文件读取
#使用read_table和read_csv函数读取菜品订单信息表
order=pd.read_table('./data/meal_order_info.csv',sep=',',encoding='gbk')
print('使用read_table函数读取的菜品订单信息表的长度为',len(order))
使用read_table函数读取的菜品订单信息表的长度为 945
#使用read_csv函数读取菜品订单信息表
order=pd.read_csv('./data/meal_order_info.csv',sep=',',encoding='gbk')
print('使用read_csv函数读取的菜品订单信息表的长度为',len(order))
使用read_csv函数读取的菜品订单信息表的长度为 945
#更改参数读取菜品订单信息表
order2=pd.read_table('./data/meal_order_info.csv',sep=';',encoding='gbk')
print('分隔符为;时菜品订单信息表的长度为',order2.head())
分隔符为;时菜品订单信息表的长度为 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 ...
#使用read_csv读取菜品订单信息表,header=None
order3=pd.read_table('./data/meal_order_info.csv',sep=',',encoding='gbk')
print('header为None时菜品订单信息表为',order3.iloc[:4,:5])
header为None时菜品订单信息表为 info_id emp_id number_consumers mode dining_table_id
0 417 1442 4 NaN 1501
1 301 1095 3 NaN 1430
2 413 1147 6 NaN 1488
3 415 1166 4 NaN 1502
# 使用UTF-8解析菜品订单信息表
order4=pd.read_table('./data/meal_order_info.csv',sep=',',header=None,encoding='utf-8')
#print('菜品订单信息表为',order4)
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_with_dtype()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._string_convert()
pandas\_libs\parsers.pyx in pandas._libs.parsers._string_box_utf8()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: invalid continuation byte
During handling of the above exception, another exception occurred:
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-11-4d3d9a20be71> in <module>
1 # 使用UTF-8解析菜品订单信息表
----> 2 order4=pd.read_table('./data/meal_order_info.csv',sep=',',header=None,encoding='utf-8')
3 #print('菜品订单信息表为',order4)
C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision)
683 )
684
--> 685 return _read(filepath_or_buffer, kwds)
686
687 parser_f.__name__ = name
C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
461
462 try:
--> 463 data = parser.read(nrows)
464 finally:
465 parser.close()
C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
1152 def read(self, nrows=None):
1153 nrows = _validate_integer("nrows", nrows)
-> 1154 ret = self._engine.read(nrows)
1155
1156 # May alter columns / col_dict
C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py in read(self, nrows)
2057 def read(self, nrows=None):
2058 try:
-> 2059 data = self._reader.read(nrows)
2060 except StopIteration:
2061 if self._first_chunk:
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader.read()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._read_rows()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_column_data()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_tokens()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._convert_with_dtype()
pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._string_convert()
pandas\_libs\parsers.pyx in pandas._libs.parsers._string_box_utf8()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: invalid continuation byte
4.1.3读/写Excel文件
1、Excel文件读取
#使用read_excel函数读取菜品订单信息
user=pd.read_excel('./data/users.xlsx')#读取文件
print('客户信息表长度:',len(user))
客户信息表长度: 734
2、Excel文件存储
import os
#使用to_excel函数将数据存储为excel文件
print('将客户信息表写入excel文件前,目录内文件列表为:\n',os.listdir('./tmp'))
user.to_excel('./tmp/userInfo.xlsx')
print('客户信息表写入excel文件后,目录内文件列表为:\n',os.listdir('./tmp'))
将客户信息表写入excel文件前,目录内文件列表为:
['userInfo.xlsx']
客户信息表写入excel文件后,目录内文件列表为:
['userInfo.xlsx']
4.1.4 任务实现
1、读取订单详情数据库数据
#读取订单详情表
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine("mysql+pymysql://root:[email protected]/testdb?charset=utf8mb4")
session = sessionmaker(bind=engine)
detail1=pd.read_sql_table('meal_order_detail1',con=engine)
print('使用read_sql_table读取订单详情表1的长度为',len(detail1))
detail2=pd.read_sql_table('meal_order_detail2',con=engine)
print('使用read_sql_table读取订单详情表2的长度为',len(detail2))
detail3=pd.read_sql_table('meal_order_detail3',con=engine)
print('使用read_sql_table读取订单详情表3的长度为',len(detail3))
使用read_sql_table读取订单详情表1的长度为 2779
使用read_sql_table读取订单详情表2的长度为 7294
使用read_sql_table读取订单详情表3的长度为 3611
2、读取订单信息csv数据
#读取订单信息表
orderInfo=pd.read_table('./data/meal_order_info.csv',sep=',',encoding='gbk')
print('订单信息表的长度为',len(orderInfo))
订单信息表的长度为 945
3、读取客户信息Excel数据
#读取客户信息表
userInfo=pd.read_excel('./data/users.xlsx',sheet_name='users1')#Anaconda 3.7版本中 'sheetname' 命令,已更新为 'sheet_name' 。
#sheet_name代表Excel表内数据的分表位置;header表示将某行数据作为列名;names表示列名,默认为none
print('订单信息表的长度为',len(userInfo))
订单信息表的长度为 734
4.2掌握DataFrame的常用操作
4.2.11 查看DataFrame的常用属性
#查看订单详情表的4个基本属性
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine("mysql+pymysql://root:[email protected]/testdb?charset=utf8mb4")
session = sessionmaker(bind=engine)
detail1=pd.read_sql_table('meal_order_detail1',con=engine)
print('订单信息表的索引为',detail1.index)
订单信息表的索引为 RangeIndex(start=0, stop=2779, step=1)
print('订单信息表的所有值为',detail1.values)
订单信息表的所有值为 [['2956' '417' '610062' ... 'NA' 'caipu/104001.jpg' '1442']
['2958' '417' '609957' ... 'NA' 'caipu/202003.jpg' '1442']
['2961' '417' '609950' ... 'NA' 'caipu/303001.jpg' '1442']
...
['6756' '774' '609949' ... 'NA' 'caipu/404005.jpg' '1138']
['6763' '774' '610014' ... 'NA' 'caipu/302003.jpg' '1138']
['6764' '774' '610017' ... 'NA' 'caipu/302006.jpg' '1138']]
print('订单信息表的列名为',detail1.columns)
订单信息表的列名为 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'],
dtype='object')
print('订单信息表的数据类型为',detail1.dtypes)
订单信息表的数据类型为 detail_id object
order_id object
dishes_id object
logicprn_name object
parent_class_name object
dishes_name object
itemis_add object
counts float64
amounts float64
cost object
place_order_time datetime64[ns]
discount_amt object
discount_reason object
kick_back object
add_inprice object
add_info object
bar_code object
picture_file object
emp_id object
dtype: object
#size、ndim和shape属性的使用
print('订单信息表的元素个数为',detail1.size)
订单信息表的元素个数为 52801
print('订单信息表的维度数为',detail1.ndim)
订单信息表的维度数为 2
print('订单信息表的形状为',detail1.shape)
订单信息表的形状为 (2779, 19)
#使用T属性进行转置
print('订单信息表转置前形状为',detail1.shape)
print('订单信息表转置后形状为',detail1.T.shape)
订单信息表转置前形状为 (2779, 19)
订单信息表转置后形状为 (19, 2779)
4.2.2 查找增删DataFrame数据
1、查看访问DataFrame中的数据
通过字典访问内部数据的方式访问DataFrame单列数据
#通过字典访问内部数据的方式访问DataFrame单列数据
order_id=detail1['order_id']
print('订单信息表中order_id的形状为','\n',order_id.shape)
订单信息表中order_id的形状为
(2779,)
通过访问属性的方式访问DataFrame单列数据
#通过访问属性的方式访问DataFrame单列数据
dishes_name=detail1.dishes_name
print('订单信息表中dish_name的形状为','\n',dishes_name.shape)
订单信息表中dish_name的形状为
(2779,)
DataFrame单列多行数据获取
#DataFrame单列多行数据获取
dishes_name5=detail1['dishes_name'][:5]
print('订单信息表中dish_name前五行数据为','\n',dishes_name5)
订单信息表中dish_name前五行数据为
0 蒜蓉生蚝
1 蒙古烤羊腿\r\n\r\n\r\n
2 大蒜苋菜
3 芝麻烤紫菜
4 蒜香包
Name: dishes_name, dtype: object
访问DataFrame多列的多行数据
#访问DataFrame多列的多行数据
orderDish=detail1[['order_id','dishes_name']][:5]
print('订单信息表中order_id和dish_name前五行数据为','\n',orderDish)
订单信息表中order_id和dish_name前五行数据为
order_id dishes_name
0 417 蒜蓉生蚝
1 417 蒙古烤羊腿\r\n\r\n\r\n
2 417 大蒜苋菜
3 417 芝麻烤紫菜
4 417 蒜香包
#访问DataFrame多行数据
order5=detail1[:][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.0 48.0 NA 2016-08-01 11:07:00
2 大蒜苋菜 0 1.0 30.0 NA 2016-08-01 11:07:00
3 芝麻烤紫菜 0 1.0 25.0 NA 2016-08-01 11:11:00
4 蒜香包 0 1.0 13.0 NA 2016-08-01 11:11:00
5 白斩鸡 0 1.0 88.0 NA 2016-08-01 11:15:00
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('订单信息表中前5行数据为','\n',detail1.head())
订单信息表中前5行数据为
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.0 49.0 NA 2016-08-01 11:05:00
1 蒙古烤羊腿\r\n\r\n\r\n 0 1.0 48.0 NA 2016-08-01 11:07:00
2 大蒜苋菜 0 1.0 30.0 NA 2016-08-01 11:07:00
3 芝麻烤紫菜 0 1.0 25.0 NA 2016-08-01 11:11:00
4 蒜香包 0 1.0 13.0 NA 2016-08-01 11:11:00
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
print('订单信息表中后5行数据为','\n',detail1.tail())
订单信息表中后5行数据为
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.0 10.0 NA 2016-08-10 21:56:00 NA
2775 0 1.0 40.0 NA 2016-08-10 21:56:00 NA
2776 0 1.0 13.0 NA 2016-08-10 22:01:00 NA
2777 0 1.0 30.0 NA 2016-08-10 22:03:00 NA
2778 0 1.0 33.0 NA 2016-08-10 22:04:00 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
(2)DataFrame的loc、iloc访问方式
.loc[行索引名称或条件,列索引名称]
.iloc[行索引位置,列索引位置]
#使用loc和iloc实现单列切片
dishes_name1=detail1.loc[:,'dishes_name']
print('使用loc提取dishes_name列的size为',dishes_name1.size)
使用loc提取dishes_name列的size为 2779
dishes_name2=detail1.iloc[:,3]
print('使用loc提取第三列的size为',dishes_name2.size)
使用loc提取第三列的size为 2779
#使用loc和iloc实现多列切片
orderDish1=detail1.loc[:,['order_id','dishes_name']]
print('使用loc提取order_id和dishes_name列的size为',orderDish1.size)
使用loc提取order_id和dishes_name列的size为 5558
orderDish2=detail1.iloc[:,[1,3]]
print('使用iloc提取第1和第3列的size为',orderDish2.size)
使用iloc提取第1和第3列的size为 5558
#使用loc、iloc实现花式切片
print('列名为order_id和dishes_name的列名为3的数据为:\n',detail1.loc[3,['order_id','dishes_name']])
列名为order_id和dishes_name的列名为3的数据为:
order_id 417
dishes_name 芝麻烤紫菜
Name: 3, dtype: object
print('列名为order_id和dishes_name的行名为2、3、4、5、6的数据为:\n',detail1.loc[2:6,['order_id','dishes_name']])
列名为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
print('列位置为1和3的行位置为3的数据为:\n',detail1.iloc[3,[1,3