데이터 분석 기초 | 데이터 상하/좌우 병합 | concat 함수 | append 함수 | merge 함수 | join 함수 | suffix, lsuffix, rsuffix 사용법 | combine_first 함수

    728x90

     

    1. 데이터 병합

     

    ▶ 판다스_데이터 병합

    : 판다스에 있는 함수를 이용해 흩어져 있는 데이터를 연결하고 병합

    : 판다스의 시리즈, 데이터프레임같은 객체의 내부는 축마다 이름이 있기 때문에 쉽게 병합 가능

    : concat() 함수append() 함수 이용

     

     

    ▶ 라이브러리 설치 및 가져오기

    import pandas as pd
    import numpy as np

     


    2. 데이터 상·하로 병합하기

     

    2-1) concat() 

     

    ▶ menu1과 menu2라는 2개의 시리즈를 하나의 시리즈로 병합

    menu1 = pd.Series(['파스타', '라면', '냉면'], index = [1, 2, 3])
    menu2 = pd.Series(['돈가스', '피자', '치킨'], index = [4, 5, 6])
    pd.concat([menu1, menu2])

     

    ▶ data1과 data2 병합

    data1 = pd.DataFrame({'음식명' : ['돈가스', '피자', '초밥', '치킨', '탕수육'],
                         '카테고리' : ['일식', '양식', '일식', '양식', '중식']})
    
    data1
    data2 = pd.DataFrame({'음식명' : ['갈비탕', '냉면', '짜장면', '파스타', '라멘'],
                         '카테고리' : ['한식', '한식', '중식', '양식', '일식']})
    
    data2
    pd.concat([data1, data2])

    >> 인덱스 값이 01234가 반복되고 있음

     

    ▶ 매개변수 ignore _index = True

    : 새로운 인덱스 번호 부여

    pd.concat([data1, data2], ignore_index = True)

     

    ▶ 매개변수 keys = 

    : 데이터가 연결되기 전에 어떤 데이터에서 온 것인지 구분해줌
    : keys = 원하는 이름으로 입력

    pd.concat([data1, data2], keys = ['data1+', 'data2+'])


    ▶ data3 만들기

    data3 = pd.DataFrame({'음식명' :['갈비탕', '냉면', '짜장면', '파스타', '라멘'],
                         '판매인기지역' : ['서울', '부산', '제주', '제주', '서울']})
    
    data3

     

    ▶ data1과 data3 병합

    : 없는 값은 NaN으로 표시됨

    pd.concat([data1, data3], ignore_index = True)

     

    ▶ 매개변수 join = 'inner'

    : 내부조인, 즉 교집합인 부분만 출력

    pd.concat([data1, data3], ignore_index = True, join = 'inner')

     

    2-2) append() 

    : append() 함수보다는 concat() 함수를 더 자주 이용함

     

    ▶ data1에 data2 병합

    data1.append(data2, ignore_index = True)

     

    ▶ data1에 data3 병합

    data1.append(data3, ignore_index = True)

     


    3. 데이터 좌·우로 병합하기

     

     

    ▶ 데이터 좌·우 병합

    : 데이터의 열을 축 삼아 2개 이상의 데이터를 좌·우로 합침
    : 판다스의 concat(), merge(), join() 함수 사용

     

    3-1) 좌우로 단순 병합

     

    ▶ concat(   , axis = 1)

    : axis = 1은 열을 기준으로

    : concat() 데이터를 병합한다는 뜻

    pd.concat([data1, data2], axis = 1)

     

    3-2) 특정 열을 기준으로 데이터 병합

     

    3-2-1) merge() 함수로 병합하기

     

    ▶ merge()

    : 데이터 병합은 일반적으로 merge() 함수 사용

    : SQL이나 관계형 데이터베이스의 join 연산과 유사

    : inner join(교집합) 방식으로 작동

    → 두 데이터의 공통 열 또는 인덱스를 기준으로 데이터를 병합함

    → 이 때 기준이 되는 열과 행 데이터를 key라고 함

     

    * data4와 data5 병합

    data4 = pd.DataFrame({'음식명' : ['돈가스', '피자', '초밥', '치킨', '탕수육', '갈비탕', '냉면', '짜장면', '파스타', '라멘'],
                         '카테고리' : ['일식', '양식', '일식', '양식', '중식', '한식', '한식', '중식', '양식', '일식']})
    
    data4
    data5 = pd.DataFrame({'음식명' : ['탕수육', '짜장면', '돈가스', '치킨', '파스타', '갈비탕', '초밥'],
                         '판매인기지역' : ['서울', '부산', '제주', '서울', '서울', '제주', '부산']})
    
    data5
    pd.merge(data4, data5)

    >> 2개의 데이터프레임을 merge하면 자동으로 공통 열인 '음식명'을 기준으로 데이터를 합치고, 그 열이 key가 됨

    >> data4는 10행, data5는 7행인데 교집합으로 병합되었기 때문에 합쳐진 데이터의 길이는 7이 됨

     

     

    ▶ 매개변수 how = 'outer'

    : outer join(합집합) 방식으로 작동

    : 2개 데이터 중 키 값이 한쪽에만 있더라도 전체가 출력됨

    pd.merge(data_4, data_5, how='outer')

     

    ▶ 매개변수 how = 'left / right'

     

    * how = 'left'

    : 왼쪽의 data4를 기준으로 병합

    pd.merge(data4, data5, how = 'left')

     

    * how = 'right'

    : 오른쪽의 data5를 기준으로 병합

    pd.merge(data4, data5, how = 'right')


    ▶ data6과 data7 병합

    data6 = data4.merge(data5)
    
    data6

    data7 = pd.DataFrame({'판매인기지역' : ['서울', '부산', '제주'],
                          '오픈시간' : ['10시', '12시', '11시']})
    
    data7

    pd.merge(data6, data7)

    >> data6의 판매인기지역에 data7의 데이터가 병합됨

     

     

    3-2-2) join() 함수로 병합하기

     

    ▶ join()

    : merge() 함수 대신 join() 함수로 데이터 병합 가능

    : 사용법이 직관적이지 않아 잘 사용하지는 않음

     

    * data6과 data7 병합 : 에러

    data6.join(data7)

    >> key가 되는 열에 suffix를 지정하지 않아서 error 발생함

    >> join() 함수에서는 병합할 데이터에 겹치는 열이 있으면 각각 접미사(suffix)를 지정해줘야 함

     

     

    ▶ data6과 data7 병합 : 매개변수 lsuffix = / rsuffix = 

    data6.join(data7, lsuffix = '_left_key', rsuffix = '_right_key')

     

    ▶ data6과 data7 병합 : .setindex(' '), 매개변수 on = 

    : on = 에 기준이 되는 열 지정

    data6.join(data7.set_index('판매인기지역'), on = '판매인기지역')

     


    4. key로 데이터 병합

     

    4-1) 하나의 key에 동일한 데이터가 여러 개 있는 경우의 데이터 병합

     

    * menu_price

    menu_price = pd.DataFrame({
        '음식명' : ['돈가스', '돈가스', '파스타', '파스타', '파스타'],
        '가격' : [9000, 10000, 12000, 13000, 15000]
    })
    
    menu_price

     

    * menu_location

    menu_location = pd.DataFrame({
        '음식명' : ['돈가스', '파스타','파스타', '피자', '피자'],
        '매장위치' : ['삼성동', '명동', '홍대입구', '이태원', '가로수길']
    })
    
    menu_location

     

    menu_price와 menu_location 병합하기

    pd.merge(menu_price, menu_location)

     

    4-2) 열 이름은 같지만 key가 될 수 없는 경우의 데이터 병합

     

    * menu_data1

    menu_data1 = pd.DataFrame({
        '음식명' : ['초밥', '초밥', '갈비탕', '짜장면', '짜장면'],
        '판매날짜' : ['2023-06-20', '2023-06-22', '2023-06-20', '2023-06-20', '2023-06-22'],
        '메모' : ['20000', '15000', '13000', '7000', '9000']})
    
    menu_data1

     

    * menu_data2

    menu_data2 = pd.DataFrame({'음식명' : ['초밥', '갈비탕', '짜장면'],
                              '메모' : ['일식', '한식', '중식']})
    
    menu_data2

     

     menu_data1과 menu_data2 병합하기

    pd.merge(menu_data1, menu_data2)

    >> 아무 데이터도 출력되지 않음

    >> 동일한 이름의 열 중에 어떤 열을 기준으로 합치는지 정해주지 않았기 때문

     

     

    ▶ 매개변수 on = 으로 기준이 되는 열 지정해주기

    pd.merge(menu_data1, menu_data2, on = '음식명')

    >> 합쳐진 결과를 보면 기준 열은 아니지만 이름이 같은 열은 _x, _y 와 같은 suffix가 붙음

    >> 열 이름 수정하기 작업으로 적당한 이름으로 수정

     

     

    4-3) 서로 다른 열을 가진 데이터 병합하기 

     

    * menu_price

    menu_price = pd.DataFrame({
        '음식명' : ['초밥', '초밥', '갈비탕', '짜장면'],
        '가격' : [20000, 15000, 13000, 7000]})
    
    menu_price

     

    * menu_score

    menu_score = pd.DataFrame({
        '메뉴명' : ['초밥', '갈비탕', '갈비탕', '짜장면'],
        '단가' : [10000, 7000, 6000, 3000]})
    
    menu_score

     

     menu_price과 menu_score 병합하기

     

    * 매개변수 left_on = / right_on = 

    : 각각 left_on과 right_on에 각 데이터의 기준 열을 지정

    pd.merge(menu_price, menu_score, left_on = '음식명', right_on = '메뉴명')

     

    * 음식명과 메뉴명의 데이터 값이 같으므로 하나는 .drop

    pd.merge(menu_price, menu_score, left_on = '음식명', right_on = '메뉴명').drop('메뉴명', axis = 1)

     


    5. 인덱스로 데이터 병합

     

    5-1) 인덱스 기준으로 데이터 병합하기

     

    * menu_data1

    menu_data1 = pd.DataFrame([20000, 15000, 12000, 13000, 15000],
                             index = ['초밥', '초밥', '갈비탕', '갈비탕', '갈비탕'], columns = ['가격'])
    
    menu_data1

     

    * menu_data2

    menu_data2 = pd.DataFrame([12000, 7000, 8000, 9000, 25000],
                             index = ['갈비탕', '짜장면', '짜장면', '짜장면', '탕수육'], columns = ['가격'])
    
    menu_data2

     

     menu_data1과 menu_data2 병합하기

    : 데이터 그대로 병합

    pd.merge(menu_data1, menu_data2, how = 'outer')

     

    *  매개변수 left_index = / right_index = 

    : menu_data1과 menu_data2의 데이터를 outer로 병합하되 각 인덱스를 표시하면서 합침

    : 조인 방식을 'outer'로 지정했기 때문에 값이 없는 일부 데이터는 결측값으로 표시됨

    pd.merge(menu_data1, menu_data2, how = 'outer', left_index = True, right_index = True)

     

    5-2) 인덱스가 겹치는 데이터를 병합할 때의 결측값 처리

     

    * data1

    data1 = pd.DataFrame({'음식명' : ['돈가스', np.nan, '초밥', '치킨', np.nan],
                         '카테고리' : ['일식', '양식', np.nan, '양식', '중식'],
                         '판매인기지역' : [np.nan, '부산', '제주', '제주', '서울']})
    
    data1

     

    * data2

    data2 = pd.DataFrame({'음식명' : [np.nan, '냉면', '초밥', '치킨', '탕수육'],
                         '카테고리' : ['일식', np.nan, '한식', '양식', np.nan]})
    
    data2

     

    data1과 data2 병합하기

     

    * .combine_first( )

    : data1과 data2의 데이터를 통해 결측값의 값을 맞춰볼 수 있음

    data1.combine_first(data2)

    >> data2에는 판매인기지역 열이 존재하지 않기 때문에 여전히 data1의 결측값이 남아있음

     

     

    5-3) 숫자 데이터_넘파이의 where() 함수로 처리

     

    * data_a

    data_a = pd.Series([51, np.nan, 260, np.nan, 182],
                      index = ['a', 'b', 'c', 'd', 'e'])
    
    data_a

     

    *data_b

    data_b = pd.Series(np.arange(len(data_a), dtype = np.float64),
                      index = ['a', 'b', 'c', 'd', 'e'])
    
    data_b[-1] = np.nan
    
    data_b

     

    * where() 함수로 배열 확인하기

    np.where(pd.isnull(data_a), data_b, data_a)

     

    * data_a와 data_b의 데이터 결측값이 채워짐

    data_a = np.where(pd.isnull(data_a), data_b, data_a)
    data_a = pd.Series(data_a)
    
    data_a

    728x90

    댓글