[Python] 신규 데이터와 기존 데이터를 배열과 집합으로 비교하기

어쩌다·2022년 9월 16일
0

[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:
                # new data에 기존 데이터의 모선항차가 없을 시를 걸러서 데이터를 담기
                compare_data = compare_new_data_dict + \
                    compare_now_data_dict  # 기존, 최근 데이터 모두 합한 후
                for index, get in enumerate(compare_data, 1):
                    if get['oid'] == checked:  # oid를 통해 비교
                        checked_data.append(get)  # 비교한 것만 append

        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 = []
  1. 먼저 데이터를 비교하기 위해서는 기준이 필요하다.
  2. 선석은 모선항차가 유일하기 때문에 모선항차를 기준으로 하여 비교하도록 한다.
  3. 따라서 data_arr_ch 배열은 모선항차를 비교하기 위해서 모선항차만 담아두는 배열이다.
  4. now_data_dict 해당 배열은 dict 타입으로 된 실데이터(크롤링한 데이터)를 담아서 비교하는 배열이다.

기존 데이터와 신규 데이터를 수집

기존 데이터를 pymysql을 통해 가져오기

import pymysql
import pymysql.cursors

  	def select_all(trminlCode):
        try:
            cur = con.cursor()  # cursor 생성
            sql = "SELECT * FROM tbname WHERE TRUE AND trminlCode = '{}'".format(
                trminlCode)
            print(sql)
            # 데이타 Fetch
            cur.execute(sql)
            rows = cur.fetchall()
            return rows
        except Exception as e:
            print(e)
            cur.close()
        finally:
            cur.close()
  1. 하나의 지역에 터미널 수가 많은 데이터를 SELECT하는 것은 따로 함수를 만들었다.
  2. 해당 함수를 사용하여 기존 데이터를 가져오게 된다.

세팅한 배열에 담기

				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)
  1. 기존 데이터와 현재 데이터를 for문을 통해 세팅한 배열에다 담도록 한다.
  2. 그렇게 해야 데이터를 비교하고 가공할 수 있기 때문이다.

집합 연산하기

				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'}
--------------------------------------------------

  1. 먼저 데이터를 담은 배열을 집합 타입으로 형변환하기 위해서 set() 함수를 사용한다.
  2. 신규 데이터와 기존 데이터는 집합을 통해 연산이 가능하게 되고, &연산자를 통해 교집합을 구한다.
  3. 즉, 신규 데이터와 기존 데이터를 비교하여 '중복된 데이터만' 구한다.
  4. 이렇게 되면 신규와 기존 중에서 '기존' 데이터만 구할 수 있다.
  5. 따라서 이를 신규 데이터에서 기존 데이터를 지워버리게 되면(new - now), 남는 것은 오직 '신규' 데이터가 된다.

실데이터 비교하기

				for checked in same_check:
            if same_check:
                # new data에 기존 데이터의 모선항차가 없을 시를 걸러서 데이터를 담기
                compare_data = compare_new_data_dict + \
                    compare_now_data_dict  # 기존, 최근 데이터 모두 합한 후
                for index, get in enumerate(compare_data, 1):
                    if get['oid'] == checked:  # oid를 통해 비교
                        checked_data.append(get)  # 비교한 것만 append

        return checked_data
  1. 따라서 새로 생긴 모선항차를 기준으로 반복을 하여 실데이터를 비교해야 된다.
  2. 그러기 위해서는 기존과 신규 데이터를 모두 합한 후, 모선 항차를 기준으로 모든 데이터를 검열하도록 한다.
  3. 데이터 중 새로운 데이터는 신규 모선항차가 걸릴 것이다.
  4. 그리고 검열된 데이터를 return 해주면 끝이다.

여담

  • 예측할 수 없는 데이터나 배열, 많은 데이터를 비교할 때는 집합 연산을 쓰는 것이 가장 효율적인 것을 알았다.
  • 더 고민하면서 코딩하면 더 좋은 코드가 나올 것 같다.
profile
혼자 공부하는 공간

0개의 댓글