'verify_integrity'에 해당되는 글 1건

  1. 2016.11.28 [Python pandas] 여러개의 동일한 형태 DataFrame 합치기 : pd.concat()

분석을 하다보면 여기저기 흩어져 있는 여러 개의 데이터 테이블을 모아서 합쳐야 하는 일이 생기곤 합니다. 나를 대신해서 누군가가 데이터 전처리를 해주지 않는다고 했을 때는 말이지요.

 

특히 정규화해서 Database 관리를 하는 곳이라면 주제별로 Data Entity를 구분해서 여러 개의 Table들로 데이터가 나뉘어져 있을 것입니다.

 

특히, 데이터의 속성 형태가 동일한 데이터셋(homogeneously-typed objects)끼리 합칠 때 사용할 수 있는 pandas의 DataFrame 합치는 방법(concatenating DataFrames)으로 이번 포스팅에서는 pd.concat() 함수를 소개하겠습니다.

(R의 rbind(), cbind() 와 유사함)

 

pd.concat() 의 parameter 값들의 default setting은 아래와 같습니다. 하나씩 예를 들어가면서 소개하겠습니다.

 

 

pd.concat(objs,  # Series, DataFrame, Panel object

             axis=0,  # 0: 위+아래로 합치기, 1: 왼쪽+오른쪽으로 합치기

             join='outer', # 'outer': 합집합(union), 'inner': 교집합(intersection)

             join_axes=None, # axis=1 일 경우 특정 DataFrame의 index를 그대로 이용하려면 입력

             ignore_index=False,  # False: 기존 index 유지, True: 기존 index 무시
             keys=None, # 계층적 index 사용하려면 keys 튜플 입력

             levels=None,

             names=None, # index의 이름 부여하려면 names 튜플 입력

             verify_integrity=False, # True: index 중복 확인
             copy=True) # 복사

 

 

 

 

  (1-1) 위 + 아래로 DataFrame 합치기(rbind) : axis = 0

 

 

# importing libraries

In [1]: import pandas as pd

   ...: from pandas import DataFrame

 

 

 

# making DataFrames

In [2]: df_1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],

   ...: 'B': ['B0', 'B1', 'B2'],

   ...: 'C': ['C0', 'C1', 'C2'],

   ...: 'D': ['D0', 'D1', 'D2']},

   ...: index=[0, 1, 2])


In [3]: df_2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],

   ...: 'B': ['B3', 'B4', 'B5'],

   ...: 'C': ['C3', 'C4', 'C5'],

   ...: 'D': ['D3', 'D4', 'D5']},

   ...: index=[3, 4, 5])

 

In [4]: df_1

Out[4]:

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2


In [5]: df_2

Out[5]:

    A   B   C   D
3  A3  B3  C3  D3
4  A4  B4  C4  D4
5  A5  B5  C5  D5

 

 

 

# concatenating DataFrame1, 2 along rows, axis=0, default

In [6]: df_12_axis0 = pd.concat([df_1, df_2]) # row bind : axis = 0, default


In [7]: df_12_axis0

Out[7]:

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3
4  A4  B4  C4  D4
5  A5  B5  C5  D5

 

 

 

 

 (1-2) 왼쪽 + 오른쪽으로 DataFrame 합치기(cbind) : axis = 1

 

 

In [8]: df_3 = pd.DataFrame({'E': ['A6', 'A7', 'A8'],

   ...: 'F': ['B6', 'B7', 'B8'],

   ...: 'G': ['C6', 'C7', 'C8'],

   ...: 'H': ['D6', 'D7', 'D8']},

   ...: index=[0, 1, 2])

 

In [9]: df_1

Out[9]:

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2


In [10]: df_3

Out[10]:

    E   F   G   H
0  A6  B6  C6  D6
1  A7  B7  C7  D7
2  A8  B8  C8  D8

 

 

 

# concatenating DataFrames along columns, axis=1

In [11]: df_13_axis1 = pd.concat([df_1, df_3], axis=1) # column bind


In [12]: df_13_axis1

Out[12]:

     A   B   C   D    E    F    G   H
0  A0  B0  C0  D0  A6  B6  C6  D6
1  A1  B1  C1  D1  A7  B7  C7  D7
2  A2  B2  C2  D2  A8  B8  C8  D8

 

 

 

 

 (2-1) 합집합(union)으로 DataFrame 합치기 : join = 'outer'

 

 

In [13]: df_4 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],

    ...: 'B': ['B0', 'B1', 'B2'],

    ...: 'C': ['C0', 'C1', 'C2'],

    ...: 'E': ['E0', 'E1', 'E2']},

    ...: index=[0, 1, 3])


In [17]: df_1

Out[17]:

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2


In [18]: df_4

Out[18]:

     A   B   C   E
0  A0  B0  C0  E0
1  A1  B1  C1  E1
3  A2  B2  C2  E2


In [19]: df_14_outer = pd.concat([df_1, df_4], join='outer') # union, default


In [20]: df_14_outer

Out[20]:

     A   B   C    D    E
0  A0  B0  C0   D0  NaN
1  A1  B1  C1   D1  NaN
2  A2  B2  C2   D2  NaN
0  A0  B0  C0  NaN   E0
1  A1  B1  C1  NaN
   E1
3  A2  B2  C2  NaN   E2

 

 

 

 

 (2-2) 교집합(intersection)으로 DataFrame 합치기 : join = 'inner'

 

 

In [21]: df_14_inner = pd.concat([df_1, df_4], join='inner') # intersection


In [22]: df_14_inner

Out[22]:

    A   B   C
0  A0  B0  C0
1  A1  B1  C1
2  A2  B2  C2
0  A0  B0  C0
1  A1  B1  C1
3  A2  B2  C2

 

 

 

 

 (3) axis=1일 경우 특정 DataFrame의 index를 그대로 이용하고자 할 경우 : join_axes

 

아래에 axis=1 (왼쪽+오른쪽) 인 경우, join='outer', join='inner', join_axes=[df.index] 의 3개 방법을 소개하였습니다. 합쳐진 DataFrame의 index 를 유심히 비교해보시기 바랍니다.

 

 

In [23]: df_1

Out[23]:

     A   B   C   D
 0  A0  B0  C0  D0
 1  A1  B1  C1  D1
 2  A2  B2  C2  D2


In [24]: df_4

Out[24]:

     A   B   C   E
 0  A0  B0  C0  E0
 1  A1  B1  C1  E1
 3  A2  B2  C2  E2

 

# comparison 1
In [25]: df_14_outer_axis1 = pd.concat([df_1, df_4], join='outer', axis=1) # default


In [26]: df_14_outer_axis1

Out[26]:

      A    B    C    D    A    B    C    E
 0   A0   B0   C0   D0   A0   B0   C0   E0
 1   A1   B1   C1   D1   A1   B1   C1   E1
 2   A2   B2   C2   D2  NaN  NaN  NaN  NaN
 3  NaN  NaN  NaN  NaN   A2   B2   C2   E2

 

# comparison 2 

In [29]: df_14_inner_axis1 = pd.concat([df_1, df_4], join='inner', axis=1)


In [30]: df_14_inner_axis1

Out[30]:

     A   B   C   D   A   B   C   E
 0  A0  B0  C0  D0  A0  B0  C0  E0
 1  A1  B1  C1  D1  A1  B1  C1  E1

 

 

# reuse the exact index from the original DataFrame : join_axes

In [31]: df_14_join_axes_axis1 = pd.concat([df_1, df_4], join_axes=[df_1.index], axis=1)


In [32]: df_14_join_axes_axis1

Out[32]:

     A   B   C   D    A    B    C    E
 0  A0  B0  C0  D0   A0   B0   C0   E0
 1  A1  B1  C1  D1   A1   B1   C1   E1
 2  A2  B2  C2  D2  NaN  NaN  NaN  NaN

 

 

 

 (4) 기존 index를 무시하고 싶을 때 : ignore_index

 

 

In [33]: df_5 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],

    ...: 'B': ['B0', 'B1', 'B2'],

    ...: 'C': ['C0', 'C1', 'C2'],

    ...: 'D': ['D0', 'D1', 'D2']},

    ...: index=['r0', 'r1', 'r2'])


In [34]: df_6 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],

    ...: 'B': ['B3', 'B4', 'B5'],

    ...: 'C': ['C3', 'C4', 'C5'],

    ...: 'D': ['D3', 'D4', 'D5']},

    ...: index=['r3', 'r4', 'r5'])

 

In [35]: df_56_with_index = pd.concat([df_5, df_6], ignore_index=False) # default


In [36]: df_56_with_index

Out[36]:

     A   B   C   D
 r0  A0  B0  C0  D0
 r1  A1  B1  C1  D1
 r2  A2  B2  C2  D2
 r3  A3  B3  C3  D3
 r4  A4  B4  C4  D4
 r5  A5  B5  C5  D5

 

# if you want ignore current index, use 'ignore_index=True'

In [37]: df_56_ignore_index = pd.concat([df_5, df_6], ignore_index=True)# index 0~(n-1)


In [38]: df_56_ignore_index

Out[38]:

    A   B   C   D
 0  A0  B0  C0  D0
 1  A1  B1  C1  D1
 2  A2  B2  C2  D2
 3  A3  B3  C3  D3
 4  A4  B4  C4  D4
 5  A5  B5  C5  D5

 

 

 

 

 (5) 계층적 index (hierarchical index) 만들기 : keys 

 

 

# concatenating DataFrames : Construct hierarchical index using 'keys'


In [40]: df_56_with_keys = pd.concat([df_5, df_6], keys=['df_5', 'df_6'])


In [41]: df_56_with_keys

Out[41]:

            A   B   C   D
 df_5  r0  A0  B0  C0  D0
         r1  A1  B1  C1  D1
         r2  A2  B2  C2  D2
 df_6  r3  A3  B3  C3  D3
         r4  A4  B4  C4  D4
         r5  A5  B5  C5  D5 

 

 

 

참고로, 계층적 index를 가지고 indexing 하는 방법을 아래에 예를 들어 소개하겠습니다.  'df_56_with_keys' DataFrame은 index가 1층, 2층으로 계층을 이루고 있으므로 indexing 할 때 1층용 index와 2층용 index를 따로 따로 사용하면 됩니다. 아래 예시를 참고하세요.

 

 

In [42]: df_56_with_keys.ix['df_5']

Out[42]:

     A   B   C   D
r0  A0  B0  C0  D0
r1  A1  B1  C1  D1
r2  A2  B2  C2  D2


In [43]: df_56_with_keys.ix['df_5'][0:2]

Out[43]:

     A   B   C   D
r0  A0  B0  C0  D0
r1  A1  B1  C1  D1

 

 

 

 

 (6) index에 이름 부여하기 : names

 

 

In [44]: df_56_with_name = pd.concat([df_5, df_6],

    ...: keys=['df_5', 'df_6'],

    ...: names=['df_name', 'row_number'])


In [45]: df_56_with_name

Out[45]:

                                 A   B   C   D
df_name   row_number               
df_5         r0                A0  B0  C0  D0
              r1                A1  B1  C1  D1
              r2                A2  B2  C2  D2
df_6         r3                A3  B3  C3  D3
              r4                A4  B4  C4  D4
              r5                A5  B5  C5  D5

 

 

 

 

 (7) index 중복 여부 점검 : verify_integrity

 

df_7, df_8 DataFrame에 'r2' index를 중복으로 포함시킨 후에 pd.concat() 을 적용해보겠습니다. verify_integrity=False (디폴트이므로 별도 입력 안해도 됨) 에서는 아무 에러 메시지 없이 위+아래로 잘 합쳐집니다 ('r2' index가 위+아래로 2번 중복해서 나타남).  반면에, verify_integrity=True 를 설정해주면 만약 index 중복이 있을 경우 'ValueError: Indexes have overlapping values: xxx' 에러 메시지가 뜨면서 합치기가 아예 안됩니다.

 

 

In [48]: df_7 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],

    ...: 'B': ['B0', 'B1', 'B2'],

    ...: 'C': ['C0', 'C1', 'C2'],

    ...: 'D': ['D0', 'D1', 'D2']},

    ...: index=['r0', 'r1', 'r2'])

    ...:


In [49]: df_8 = pd.DataFrame({'A': ['A2', 'A3', 'A4'],

    ...: 'B': ['B2', 'B3', 'B4'],

    ...: 'C': ['C2', 'C3', 'C4'],

    ...: 'D': ['D2', 'D3', 'D4']},

    ...: index=['r2', 'r3', 'r4'])


In [50]: df_7

Out[50]:

     A   B   C   D
r0  A0  B0  C0  D0
r1  A1  B1  C1  D1
r2  A2  B2  C2  D2


In [51]: df_8

Out[51]:

     A   B   C   D
r2  A2  B2  C2  D2
r3  A3  B3  C3  D3
r4  A4  B4  C4  D4

 

 

# concatenating DataFrames without overlap checking : verify_integrity=False

 

In [52]: df_78_F_verify_integrity = pd.concat([df_7, df_8],

    ...: verify_integrity=False) # default


In [53]: df_78_F_verify_integrity

Out[53]:

     A   B   C   D
r0  A0  B0  C0  D0
r1  A1  B1  C1  D1
r2  A2  B2  C2  D2
r2  A2  B2  C2  D2
r3  A3  B3  C3  D3
r4  A4  B4  C4  D4

 

 

# index overlap checking, using verify_integrity=True

 

In [54]: df_78_T_verify_integrity = pd.concat([df_7, df_8],

    ...: verify_integrity=True)

 

Traceback (most recent call last):

  File "<ipython-input-56-5512ad3b5016>", line 2, in <module>
    verify_integrity=True)

  File "C:\Anaconda3\lib\site-packages\pandas\tools\merge.py", line 845, in concat
    copy=copy)

  File "C:\Anaconda3\lib\site-packages\pandas\tools\merge.py", line 984, in __init__
    self.new_axes = self._get_new_axes()

  File "C:\Anaconda3\lib\site-packages\pandas\tools\merge.py", line 1073, in _get_new_axes
    new_axes[self.axis] = self._get_concat_axis()

  File "C:\Anaconda3\lib\site-packages\pandas\tools\merge.py", line 1132, in _get_concat_axis
    self._maybe_check_integrity(concat_axis)

  File "C:\Anaconda3\lib\site-packages\pandas\tools\merge.py", line 1141, in _maybe_check_integrity
    % str(overlap))

 

ValueError: Indexes have overlapping values: ['r2']

 

 

많은 도움이 되었기를 바랍니다.

 

도움이 되었다면 아래의 '공감 ~♡'를 꾹 눌러주세요. ^^

 

Posted by R Friend R_Friend

댓글을 달아 주세요