之前寫工廠進出日誌配對的python程式,工廠日誌的進出是不同筆記錄,進去刷一筆,出來刷一筆,故需要配對,找出只有刷進沒有刷出的,或只有刷出沒有刷進的。但問題在之前寫的程式太慢,因為是用for loop從第一筆往後掃描配對(已經按時間排序好),python在處理距陣運算或兩筆超長向量互相比較很快,但for loop就超慢,故我再將程式改成向量比較方式,使得1.3Mega筆資料只需數秒就比較完(若用for loop約需10倍的時間)。
#資料表df先按時間排序,再按卡號排序
df = df.sort_values(by='origitime').sort_values(by='cardno',kind='mergesort')
df = df.sort_values(by='origitime').sort_values(by='cardno',kind='mergesort')
#將進出欄,附加日期和卡號,從df資料表複製成一向量a
a = np.array(df[['io','date','cardno']])
a = np.array(df[['io','date','cardno']])
#將進出欄,附加日期和卡號,複製成一向量b,但從第二列開始複製,最後再加一列0,湊成和a的維度一樣
b = np.array(df[['io','date','cardno']].iloc[1:,:])
b = np.append(b,[[0,0,0]],axis=0)
b = np.array(df[['io','date','cardno']].iloc[1:,:])
b = np.append(b,[[0,0,0]],axis=0)
#作Boolean計算,a每一維元素是否進,b每一維元素是否出,a和b的同維元素其它資料是否相等,最後結果是Boolean向量
result = (a[:,0] == 1) & (b[:,0] == 2) & (a[:,1] == b[:,1]) & (a[:,2] == b[:,2])
result = (a[:,0] == 1) & (b[:,0] == 2) & (a[:,1] == b[:,1]) & (a[:,2] == b[:,2])
#result的後一個值和前一個值作or計算,但用向量or
result2 = result[1:] | result[:-1]
result2 = result[1:] | result[:-1]
#剛才的向量or,第一個值無法和前一個值計算,故直接原狀態補進來
df['result'] = result[0]
df['result'] = result[0]
#將剛才的向量or結果放回去資料表df,從第2筆記錄開始放。
df['result'].iloc[1:] = result2
df['result'].iloc[1:] = result2
#df['result']結果是True的該筆資料代表可以成功配對,False代表不行。
沒有留言:
張貼留言