[Python] 신규 데이터와 기존 데이터를 배열과 집합으로 비교하기
사용하는 데이터 분석
- 전에 크롤링 게시글을 올렸듯이 사용하는 데이터는 선석 정보 데이터이다.
- 선석 정보는 특성상 실시간으로 업데이트 되는 부분이 있거나 추가되는 부분이 있다.
- 따라서 신규 데이터와 기존 데이터를 비교하여 키값에 따라 업데이트된 데이터는 UPDATE 트랜잭션을 진행시키고 새로운 데이터는 INSERT 트랜잭션을 시키도록 한다.
- 이 모든 데이터는 크롤링을 통해서 수집한다.
source
new_data_arr_ch = []
now_data_arr_ch = []
compare_now_data_dict = []
compare_new_data_dict = []
checked_data = []
def data_check(new_data, now_data):
try:
for index, result in enumerate(new_data, 1):
new_data_obj_checking = result['oid']
new_data_arr_ch.append(new_data_obj_checking)
compare_new_data_dict.append(result)
for index, result in enumerate(now_data, 1):
now_data_obj_checking = result["oid"]
now_data_arr_ch.append(now_data_obj_checking)
compare_now_data_dict.append(result)
same_things = set(new_data_arr_ch) & set(now_data_arr_ch)
same_check = set(new_data_arr_ch) - set(same_things)
print("-"*50)
print("새로 생긴 모선항차", same_check)
print("-"*50)
for checked in same_check:
if same_check:
compare_data = compare_new_data_dict + \
compare_now_data_dict
for index, get in enumerate(compare_data, 1):
if get['oid'] == checked:
checked_data.append(get)
return checked_data
except Exception as e:
print(e)
데이터 가공을 위한 배열 세팅
new_data_arr_ch = []
now_data_arr_ch = []
compare_now_data_dict = []
compare_new_data_dict = []
checked_data = []
- 먼저 데이터를 비교하기 위해서는 기준이 필요하다.
- 선석은 모선항차가 유일하기 때문에 모선항차를 기준으로 하여 비교하도록 한다.
- 따라서
data_arr_ch
배열은 모선항차를 비교하기 위해서 모선항차
만 담아두는 배열이다.
now_data_dict
해당 배열은 dict 타입으로 된 실데이터(크롤링한 데이터)를 담아서 비교하는 배열이다.
기존 데이터와 신규 데이터를 수집
기존 데이터를 pymysql을 통해 가져오기
import pymysql
import pymysql.cursors
def select_all(trminlCode):
try:
cur = con.cursor()
sql = "SELECT * FROM tbname WHERE TRUE AND trminlCode = '{}'".format(
trminlCode)
print(sql)
cur.execute(sql)
rows = cur.fetchall()
return rows
except Exception as e:
print(e)
cur.close()
finally:
cur.close()
- 하나의 지역에 터미널 수가 많은 데이터를 SELECT하는 것은 따로 함수를 만들었다.
- 해당 함수를 사용하여 기존 데이터를 가져오게 된다.
세팅한 배열에 담기
for index, result in enumerate(new_data, 1):
new_data_obj_checking = result['oid']
new_data_arr_ch.append(new_data_obj_checking)
compare_new_data_dict.append(result)
for index, result in enumerate(now_data, 1):
now_data_obj_checking = result["oid"]
now_data_arr_ch.append(now_data_obj_checking)
compare_now_data_dict.append(result)
- 기존 데이터와 현재 데이터를 for문을 통해 세팅한 배열에다 담도록 한다.
- 그렇게 해야 데이터를 비교하고 가공할 수 있기 때문이다.
집합 연산하기
same_things = set(new_data_arr_ch) & set(now_data_arr_ch)
same_check = set(new_data_arr_ch) - set(same_things)
print("-"*50)
print("새로 생긴 모선항차", same_check)
print("-"*50)
example
--------------------------------------------------
새로 생긴 모선항차 {'PSUN-017/2022', 'HHPO-0009', 'HAYN-038/2022', 'NSSP-0012', 'STIC-0001', 'SMYT-0002', 'JIYU-0023', 'SUGW-007/2022', 'KKNH-007/2022', 'SKQD-0030', 'DPPA-0010', 'DJFT-0001', 'KSLS-004/2022', 'DJHN-038/2022'}
--------------------------------------------------
- 먼저 데이터를 담은 배열을 집합 타입으로 형변환하기 위해서
set()
함수를 사용한다.
- 신규 데이터와 기존 데이터는 집합을 통해 연산이 가능하게 되고,
&
연산자를 통해 교집합을 구한다.
- 즉, 신규 데이터와 기존 데이터를 비교하여 '중복된 데이터만' 구한다.
- 이렇게 되면 신규와 기존 중에서 '기존' 데이터만 구할 수 있다.
- 따라서 이를 신규 데이터에서 기존 데이터를 지워버리게 되면(new - now), 남는 것은 오직 '신규' 데이터가 된다.
실데이터 비교하기
for checked in same_check:
if same_check:
compare_data = compare_new_data_dict + \
compare_now_data_dict
for index, get in enumerate(compare_data, 1):
if get['oid'] == checked:
checked_data.append(get)
return checked_data
- 따라서 새로 생긴 모선항차를 기준으로 반복을 하여 실데이터를 비교해야 된다.
- 그러기 위해서는 기존과 신규 데이터를 모두 합한 후, 모선 항차를 기준으로 모든 데이터를 검열하도록 한다.
- 데이터 중 새로운 데이터는 신규 모선항차가 걸릴 것이다.
- 그리고 검열된 데이터를 return 해주면 끝이다.
여담
- 예측할 수 없는 데이터나 배열, 많은 데이터를 비교할 때는 집합 연산을 쓰는 것이 가장 효율적인 것을 알았다.
- 더 고민하면서 코딩하면 더 좋은 코드가 나올 것 같다.