esproc vs python 6

本節在數據量比較大的狀況下,對比esproc和python。python

數據量:7000多條萬記錄,5個字段分別是orderid,clientid,sellerid,amount,date。總大小超過3G。app

1. 篩選8月份的交易記錄

esproc測試

image.png

A2:f.cursor()spa

根據文件f建立遊標並返回,數據掃描完將自動關閉遊標。@t, f中第一行記錄做爲字段名,不使用本選項時默認使用_1,_2,…做爲字段名. @c, 無s時用逗號分隔。若是同時有s則用s分隔。線程

A3:篩選出8月份的訂單記錄並取出結果code

esproc並行代碼:對象

image.png

A2:cursor@m(;n),@m選項,返回成多路遊標,n表示路數。這時結果可能改變原來數據的順序(篩選數據大多數狀況下也不須要保持原序)。排序

python:ip

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並行:

python

image.png

2. 計算出每一個銷售員每一年的銷售額和訂單數

esproc

image.png

A2:按照sellerid和年份進行分組,同時彙總amount和count數。只取出計算須要的字段。

esproc並行代碼

image.png

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並行

python

image.png

3. 列出客戶名單

esproc

image.png

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

python

image.png

4.找到每一個銷售員銷售額最大的3筆訂單

esproc

image.png

A3:按照sellerid分組並取amount最大的前三條記錄。A.top(n;x)存在x時,返回的是記錄。針對序列的每一個成員計算表達式x,返回前n個最小值對應的記錄。

A4:鏈接top3字段的序表組成新序表。

esproc並行代碼

image.png

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

python

image.png

小結:本節咱們用比較大的數據進行了簡單的計算,包括條件查詢、分組彙總、得到惟一值和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)
相關文章
相關標籤/搜索