esproc vs python 6

虚树星云
• 阅读 674

本节在数据量比较大的情况下,对比esproc和python。

数据量:7000多条万记录,5个字段分别是orderid,clientid,sellerid,amount,date。总大小超过3G。

1. 筛选8月份的交易记录

esproc

esproc vs python 6

A2:f.cursor()

根据文件f创建游标并返回,数据扫描完将自动关闭游标。@t, f中第一行记录作为字段名,不使用本选项时默认使用_1,_2,…作为字段名. @c, 无s时用逗号分隔。如果同时有s则用s分隔。

A3:筛选出8月份的订单记录并取出结果

esproc并行代码:

esproc vs python 6

A2:cursor@m(;n),@m选项,返回成多路游标,n表示路数。这时结果可能改变原来数据的顺序(筛选数据大多数情况下也不需要保持原序)。

python:

import time  
   
import pandas as pd  
   
import numpy as np  
   
s = time.time()  
   
chunksize=1000000  
   
order_data = pd.read_csv('E:\\orders_big_data\\orders.csv',iterator=True,chunksize=chunksize)  
   
i = 0  
   
month_8_list = []  
   
for chunk in order_data:  
   
    chunk['date'] = pd.to_datetime(chunk['date'])  
   
    chunk_month_8 = chunk[chunk['date'].dt.month==8]  
   
    month_8_list.append(chunk_month_8)  
   
month_8 = pd.concat(month_8_list,ignore_index=True)  
   
print(month_8)  
   
e = time.time()  
   
print(e-s)

定义chunksize大小为1000000万条记录。

pd.read_csv(fileorbuf,iterator,chunksize) iterator,返回一个TextFileReader 对象,以便逐块处理文件,chunksize文件块大小。

循环读取文件,每次都取chunksize的大小,筛选出8月份的记录,放入初始化的list中。

合并list中的dataframe得到结果。

pandas本身不支持并行,所以这里没有python的并行测试。

结果:

esproc单线程

esproc vs python 6

esproc并行:

esproc vs python 6

python

esproc vs python 6

esproc vs python 6

2. 计算出每个销售员每年的销售额和订单数

esproc

esproc vs python 6

A2:按照sellerid和年份进行分组,同时汇总amount和count数。只取出计算需要的字段。

esproc并行代码

esproc vs python 6

python:

import time  
   
import pandas as pd  
   
import numpy as np  
   
s = time.time()  
   
chunksize=1000000  
   
order_data = pd.read_csv('E:\\orders_big_data\\orders.csv',usecols=['sellerid','date','amount'],iterator=True,chunksize=chunksize)  
   
chunk_g_list = []  
   
for chunk in order_data:  
   
    chunk['date'] = pd.to_datetime(chunk['date'])  
   
    chunk['y'] = chunk['date'].dt.year  
   
    chunk_g = chunk.groupby(by=['sellerid','y']).agg(['sum','count']).reset_index()  
   
    chunk_g_list.append(chunk_g)  
   
order_group = pd.concat(chunk_g_list,ignore_index=True).groupby(by=['sellerid','y'],as_index=False).agg({('amount','sum'):['sum'],('amount','count'):['sum']})      
   
order_group.columns = ['sellerid','y','amount','count']  
   
print(order_group)  
   
e = time.time()  
   
print(e-s)

定义chunksize为100万

pd.read_csv(fileorbuf,usecols,iterator,chunksize)usecols是取出需要的字段。

按照chunksize循环读取数据

转换date字段的格式为pandas的datetime格式

新增一列年份y

df.groupby(by),按照sellerid和y进行分组。df.agg(),对分组数据进行多种计算。这里是对分组数据amount进行sum和count计算。

将结果放入list中

合并list中的df,然后再按照sellerid和y分组同时计算amount的sum值,(amount,count)的sum值。

结果:

esproc和esproc并行

esproc vs python 6

python

esproc vs python 6

esproc vs python 6

3. 列出客户名单

esproc

esproc vs python 6

A2:游标读取clientid字段

A3:cs.id(x)获取游标cs中字段x的不同值形成的序列。

python:

import time  
   
import pandas as pd  
   
import numpy as np  
   
s = time.time()  
   
chunksize=1000000  
   
order_data = pd.read_csv('E:\\orders_big_data\\orders.csv',usecols = ['clientid'],iterator=True,chunksize=chunksize)  
   
client_set = set()  
   
for chunk in order_data:  
   
    client_set = client_set|set(chunk['clientid'].values)  
   
print(pd.Series(list(client_set)))  
   
e = time.time()  
   
print(e-s)

定义chunksize,100万

pd.read_csv(),usecols参数是读取的字段,这里只读取clientid字段。

定义一个集合

按照chunksize循环数据,取chunk的clientid字段的值组成集合并与原来的集合求并集,最终的集合即为客户的名单.

为了便于查看将其转成series结构

结果:

esproc

esproc vs python 6

python

esproc vs python 6

esproc vs python 6

4.找到每个销售员销售额最大的3笔订单

esproc

esproc vs python 6

A3:按照sellerid分组并取amount最大的前三条记录。A.top(n;x)存在x时,返回的是记录。针对序列的每个成员计算表达式x,返回前n个最小值对应的记录。

A4:连接top3字段的序表组成新序表。

esproc并行代码

esproc vs python 6

python:

import time  
   
import pandas as pd  
   
import numpy as np  
   
s = time.time()  
   
chunksize=1000000  
   
order_data = pd.read_csv('E:\\orders_big_data\\orders.csv',iterator=True,chunksize=chunksize)  
   
group_list = []  
   
for chunk in order_data:  
   
    for_inter_list = []  
   
    top_n = chunk.groupby(by='sellerid',as_index=False)  
   
    for index,group in top_n:  
   
        group = group.sort_values(by='amount',ascending=False).iloc[:3]  
   
        for_inter_list.append(group)  
   
    for_inter_df = pd.concat(for_inter_list,ignore_index=True)      
   
    group_list.append(for_inter_df)  
   
top_n_gr = pd.concat(group_list,ignore_index=True).groupby(by='sellerid',as_index=False)  
   
top_n_list=[]  
   
for index,group in top_n_gr:  
   
    group = group.sort_values(by='amount',ascending=False).iloc[:3]  
   
    top_n_list.append(group)  
   
top_3 = pd.concat(top_n_list)  
   
print(top_3)  
   
e = time.time()  
   
print(e-s)

定义一个list,用来存放每个chunk生成的df

循环数据

定义一个循环内的list,用来存放分组以后的df

按照sellerid分组

循环分组,按照amount排序,ascending=Falese表示倒序排序,取前三个,然后将结果放入for循环内的list中

合并循环内list的df

循环结束后,合并最初定义的list中的df

再次按照sellerid分组

循环分组,按照amount排序,ascending=Falese表示倒序排序,取前三个

合并这次得到结果,得到每个销售员销售额最大的 3 笔订单

结果:

esproc

esproc vs python 6

python

esproc vs python 6

esproc vs python 6

小结:本节我们用比较大的数据进行了简单的计算,包括条件查询、分组汇总、获得唯一值和topn。从代码的复杂度和运行速度看,esproc都占据了优势,esproc可以轻松的通过并行提高运行效率,充分发挥多核cpu的优势,而python则很难做到。第四例中,python进行了多次循环、排序、合并。我尝试了使用python原生库做第4例的题目,由于一直都是对比的pandas所以这里没有重点介绍,运行效率比pandas快(耗时:183.164),但仍没有esproc快,这里仅供大家参考。python可以根据内存的大小调节chunksize的大小,在内存允许的情况下chunksize越大,运行效率越高。

第四例,python的另一种代码

s = time.time()  
   
seller_dic = {}  
   
with open('E:\\orders_big_data\\orders2.csv') as fd:  
   
    i=0  
   
    for line in fd:  
   
        if i ==0:  
   
            cols = line.strip().split(',')  
   
            i+=1  
   
        else:  
   
            ss = line.strip().split(',')  
   
            if len(ss) != 5:  
   
                continue  
   
            orderid = ss[0]  
   
            clientid = ss[1]  
   
            sellerid = int(ss[2])  
   
            amount = float(ss[3])  
   
            date = ss[4]              
   
            if sellerid not in seller_dic:  
   
                seller_dic[sellerid]={}  
   
                seller_dic[sellerid][amount] = ss  
   
            else:  
   
                if len(seller_dic[sellerid])<3:  
   
                    seller_dic[sellerid][amount] = ss  
   
                else:  
   
                    if amount>min(seller_dic[sellerid].keys()):  
   
                        seller_dic[sellerid].pop(min(seller_dic[sellerid].keys()))  
   
                        seller_dic[sellerid][amount]=ss                      
   
seller_list = sorted(seller_dic.items(),key=lambda x:x[0])  
   
top_3_list = []  
   
for item in seller_list:  
   
    for j in sorted(item[1].items(),key=lambda x:x[0],reverse=True):  
   
        top_3_list.append(j[1])  
   
top_3_df = pd.DataFrame(top_3_list,columns=cols)          
   
print(top_3_df)  
   
e = time.time()  
   
print(e-s)
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
SQL语句优化方式
_MYSQL性能_最大数据量抛开数据量和并发数,谈性能都是扯淡(扯的最疼的那种).Mysql没有限制单表最大记录数,它取决与操作系统对文件大小的限制文件系统单文件大小限制FAT32(采用32位二进制数(https://www.oschina.net/action/GoToLink?urlh
Stella981 Stella981
4年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
4年前
Python 学生管理
原文链接: Python学生管理(https://my.oschina.net/ahaoboy/blog/1526102)python3练手 codingutf8学生类classStu:三个字段id字符串,name字符串,score小数def__init__(sel
Stella981 Stella981
4年前
Asp.NetCore 3.1 EFCore处理Mysql的分库分表
一、什么情况下需要分库分表?Mysql单表数据量超过500万条。二、Asp.netCore技术栈,分库分表的解决方案有哪些?1、阿里云的DRDS2、Mycat 数据库分库分表中间件;3、TiDB;三、以上3种解决方案各自的特点:1、阿里云DRDS是收费的商业版,价格稍贵,但是比S
Stella981 Stella981
4年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
4年前
MySQL ORDER BY主键id加LIMIT限制走错索引
背景及现象report\_product\_sales\_data表数据量2800万;经测试,在当前数据量情况下,orderby主键id,limit最大到49的时候可以用到索引report\_product\_sales\_data\_hq\_code\_orgz\_id\_index,大于49时就走PRIMARY主键索引。
Stella981 Stella981
4年前
Eg挨蒙—Zabbix监控进程占cpu和内存大小及批量监控端口
监控简介:通过shell脚本的方式,实现对进程占cpu百分比和内存大小的监控,通过python脚本方式,实现批量监控服务器端口。一、监控进程占cpu的百分比和内存的大小1、在agent端编写脚本\root@monitorsbin\$cat/usr/local/zabbix/scripts/processtatus.sh!/
Stella981 Stella981
4年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
线上SQL超时场景分析-MySQL超时之间隙锁 | 京东物流技术团队
前言之前遇到过一个由MySQL间隙锁引发线上sql执行超时的场景,记录一下。背景说明分布式事务消息表:业务上使用消息表的方式,依赖本地事务,实现了一套分布式事务方案消息表名:mqmessages数据量:3000多万索引:createtime和statuss
clickhouse 优化实践,万级别QPS数据毫秒写入和亿级别数据秒级返回 | 京东云技术团队
1、背景魔笛活动平台目前在采集每个活动的用户行为数据并进行查询,解决线上问题定位慢,响应不及时的问题,提升客诉的解决效率。目前每天采集的数据量5000万,一个月的数据总量15亿,总数据量40亿,随着接入的活动越来越多,采集上报的数据量也会越来越大。目
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这