이번 포스팅에서는 Python pandas 의 Series, DataFrame의 행(row)과 열(column)에 대해서
- 생성 (creation)
- 선택 (selection, slicing and indexing)
- 삭제 (drop, delete)
하는 방법에 대해서 알아보겠습니다.
외부 데이터셋을 불러오거나 직접 만든 다음에 데이터 전처리하는데 있어 수시로 사용하는 가장 기본이 되는 데이터 조작 기법이 행, 열 생성, 선택, 삭제입니다.
그동안의 포스팅을 따라해보신 분이라면 이미 많이 익숙해졌을 텐데요, 체계적으로 정리도 해보고, 복습도 해볼 겸 예를 들어서 설명해보겠습니다.
(1) Series 생성 및 Series 원소 선택 (element selection, indexing) |
pd.Series() 를 써서 별도의 index label 이 없는 간단한 Series 를 만들어 보겠습니다.
(index는 0, 1, 2, ... 정수가 자동 부여됨)
# importing library
In [1]: import numpy as np
In [2]: import pandas as pd
# pd.Series with ndarrary data
In [3]: Seri = pd.Series([0., 1., 2., 3., 4.])
In [4]: Seri
Out[4]:
0 0.0 1 1.0 2 2.0 3 3.0 4 4.0 dtype: float64
|
이제 Series의 index 위치나 조건을 가지고 indexing 을 해보겠습니다.
# Slicing pd.Series like ndarray-like
In [5]: Seri[0]
Out[5]: 0.0
In [6]: Seri[:3]
Out[6]:
0 0.0 1 1.0 2 2.0 dtype: float64
In [7]: Seri[Seri >= Seri.mean()]
Out[7]:
2 2.0 3 3.0 4 4.0 dtype: float64
In [8]: Seri[[4, 2, 0]]
Out[8]:
4 4.0 2 2.0 0 0.0 dtype: float64
|
다음으로, index에 label을 할당해준 Series를 만들어보고, 특정 index label을 지정해서 indexing을 해보겠습니다.
# pd.Series with index name passed
In [9]: Seri_ix = pd.Series([0., 1., 2., 3., 4.], index=['a', 'b', 'c', 'd', 'e'])
In [10]: Seri_ix
Out[10]:
a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
# Slicing with index label
In [11]: Seri_ix[['a', 'b', 'e']]
Out[11]:
a 0.0 b 1.0 e 4.0 dtype: float64
In [12]: Seri_ix.get(['a', 'b', 'e']) # get() method
Out[12]:
a 0.0 b 1.0 e 4.0 dtype: float64
|
특정 index label 을 지정해서 값(value)을 할당해보겠습니다.
# set values by index label In [13]: Seri_ix['a'] = 100
In [14]: Seri_ix
Out[14]:
a 100.0 b 1.0 c 2.0 d 3.0 e 4.0 dtype: float64
|
특정 index label 이 Series에 들어있는지 아닌지 확인 (boolean True, False) 해보겠습니다.
# check index label whether it is or is'not in Series
In [15]: 'a' in Seri_ix
Out[15]: True
In [16]: 'x' in Seri_ix
Out[16]: False
|
(2) DataFrame 행과 열 생성, 선택, 삭제 (creation, selection, drop of row and column) |
예제로 사용할 간단한 DataFrame을 dict 로 칼럼과 값을 매핑하고, index 를 지정해서 만들어보겠습니다. DataFrame.index 로 index 확인, DataFrame.columns 로 칼럼 확인할 수 있습니다.
# importing library and making an example DataFrame In [17]: from pandas import DataFrame
In [18]: df = DataFrame({'C1': [0., 1., 2., 3.],
...: 'C2': [4., 5., 6., 7.],
...: 'C3': [8., 9., 10., np.nan]},
...: index=['R1', 'R2', 'R3', 'R4'])
...:
In [19]: df
Out[19]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0 R3 2.0 6.0 10.0 R4 3.0 7.0 NaN
# the row and column labels
In [20]: df.index # row labels
Out[20]: Index(['R1', 'R2', 'R3', 'R4'], dtype='object')
In [21]: df.columns # column labels
Out[21]: Index(['C1', 'C2', 'C3'], dtype='object')
|
df_2 = DataFrame(df_1, index=['xx', 'xx'], columns=['xx', 'xx']) 형식처럼 기존 df_1에서 행과 열을 선별해서 df_2라는 새로운 DataFrame을 만들 수 있습니다.
In [22]: df_R1R3 = DataFrame(df, index=['R1', 'R3'])
In [23]: df_R1R3
Out[23]:
C1 C2 C3 R1 0.0 4.0 8.0 R3 2.0 6.0 10.0
In [24]: df_C1C3 = DataFrame(df, columns=['C1', 'C3'])
In [25]: df_C1C3
Out[25]:
C1 C3 R1 0.0 8.0 R2 1.0 9.0 R3 2.0 10.0 R4 3.0 NaN
In [26]: df_R3R1_C3C1 = DataFrame(df, index=['R3', 'R1'], columns=['C3', 'C1'])
In [27]: df_R3R1_C3C1
Out[27]:
C3 C1 R3 10.0 2.0 R1 8.0 0.0
|
DataFrame에서 칼럼 이름을 지정해서 선별하는 방법은 아래 예시 처럼 df[['xx', 'xx']] 처럼 하면 됩니다.
# selecting columns from DataFrame
In [28]: df
Out[28]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0 R3 2.0 6.0 10.0 R4 3.0 7.0 NaN
In [29]: df[['C1', 'C2']]
Out[29]:
C1 C2 R1 0.0 4.0 R2 1.0 5.0 R3 2.0 6.0 R4 3.0 7.0
|
DataFrame에 새로운 칼럼을 만들기 할때 (1) df['new_column'] = ... 과 (2) df.assign(new_column = ... ) 의 두가지 방법이 있습니다.
# (1) making a new column
In [30]: df['C4'] = df['C1'] + df['C2']
In [31]: df
Out[31]:
C1 C2 C3 C4 R1 0.0 4.0 8.0 4.0 R2 1.0 5.0 9.0 6.0 R3 2.0 6.0 10.0 8.0 R4 3.0 7.0 NaN 10.0
# (2-1) assign() method
In [32]: df = df.assign(C5 = df['C1']*df['C2'])
In [33]: df
Out[33]:
C1 C2 C3 C4 C5 R1 0.0 4.0 8.0 4.0 0.0 R2 1.0 5.0 9.0 6.0 5.0 R3 2.0 6.0 10.0 8.0 12.0 R4 3.0 7.0 NaN 10.0 21.0
# (2-2) the same with the above
In [34]: df.assign(C5 = lambda x: x.C1*x.C2)
Out[34]:
C1 C2 C3 C4 C5 R1 0.0 4.0 8.0 4.0 0.0 R2 1.0 5.0 9.0 6.0 5.0 R3 2.0 6.0 10.0 8.0 12.0 R4 3.0 7.0 NaN 10.0 21.0
|
DataFrame의 칼럼을 삭제하는 방법에는 (1) df.drop(['xx', 'xx'], 1) 과 (2) del df['xx'] 의 방법이 있습니다. del df['xx']은 원본 데이터프레임에서 칼럼을 삭제합니다.
# drop 'C3' column : DataFrame.drop('Column', 1)
In [35]: df_drop_C4C5 = df.drop(['C4', 'C5'], 1)
In [36]: df_drop_C4C5
Out[36]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0 R3 2.0 6.0 10.0 R4 3.0 7.0 NaN
# delete a column from original DataFrame : del DataFrame['column']
In [37]: df
Out[37]:
C1 C2 C3 C4 C5 R1 0.0 4.0 8.0 4.0 0.0 R2 1.0 5.0 9.0 6.0 5.0 R3 2.0 6.0 10.0 8.0 12.0 R4 3.0 7.0 NaN 10.0 21.0
In [38]: del df['C4'] # delete 'C4' column from the original DataFrame df directly
In [39]: del df['C5'] # delete 'C5' column from the original DataFrame df directly
In [40]: df
Out[40]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0 R3 2.0 6.0 10.0 R4 3.0 7.0 NaN
|
DataFrame의 행(row)과 열(column)을 선택할 때는 df.['xx'][0:2] 를 예를 들어 소개합니다.
In [42]: df
Out[42]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0 R3 2.0 6.0 10.0 R4 3.0 7.0 NaN
# selecting column form DataFrame
In [43]: df['C1']
Out[43]:
R1 0.0 R2 1.0 R3 2.0 R4 3.0 Name: C1, dtype: float64
In [44]: df.C1
Out[44]:
R1 0.0 R2 1.0 R3 2.0 R4 3.0 Name: C1, dtype: float64
# selecting row from DataFrame
In [45]: df[0:2]
Out[45]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0
# indexing 'column' and 'row' from DataFrame
In [46]: df['C1'][0:2]
Out[46]:
R1 0.0 R2 1.0 Name: C1, dtype: float64
In [47]: df.C1[0:2]
Out[47]:
R1 0.0 R2 1.0 Name: C1, dtype: float64
|
index label을 가지고 행(row) 선택할 때는 df.loc['xx'] 를 사용합니다.
# Select row by label : df.loc[label]
In [48]: df.loc['R1']
Out[48]:
C1 0.0 C2 4.0 C3 8.0 Name: R1, dtype: float64
In [49]: df.loc[['R1', 'R2']]
Out[49]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0
|
index의 label 이 아니라 정수(integer)로 indexing을 하려면 df.iloc[int] 를 사용해야 합니다. 만약 df.loc[int]를 사용하면 TypeError 가 발생합니다.
# TypeError: cannot do label indexing on with these indexers [0] of <class 'int'>
In [50]: df.loc[0] # TypeError
TypeError: cannot do label indexing on <class 'pandas.indexes.base.Index'> with these indexers [0] of <class 'int'>
# Select row by interger location : df.iloc[loc]
In [51]: df.iloc[0]
Out[51]:
C1 0.0 C2 4.0 C3 8.0 Name: R1, dtype: float64
In [52]: df.iloc[0:2]
Out[52]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0
|
DataFrame의 행(row) indexing할 때 df[0:2] 처럼 행의 범위를 ':'로 설정해주어도 됩니다. df[0] 처럼 정수값을 지정하면 KeyError 납니다(이때는 df.iloc[0] 을 써야 함).
# KeyError: 0 In [53]: df[0] # KeyError: 0
KeyError: 0
# Select rows : df[0:2]
In [54]: df[0:2]
Out[54]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0
|
조건을 부여해서 열을 선택할 수도 있습니다.
# Select rows by boolean vector : df[bool_vec] In [55]: df[df['C1'] <= 1.0]
Out[55]:
C1 C2 C3 R1 0.0 4.0 8.0 R2 1.0 5.0 9.0
|
선택할 칼럼을 벡터 객체로 만들어 놓고, DataFrame에서 벡터 객체에 들어있는 칼럼만 선별해올 수도 있겠지요. 분석 프로세스를 자동화하려고 할 때 선행 분석 결과를 받아서 벡터 객체로 만들어 놓고, 이를 받아서 필요한 변수만 선별할 때 종종 사용하곤 합니다.
# Select columns by column vector : df[col_bool_vec]
In [56]: df_col_selector = ['C1', 'C2']
In [57]: df[df_col_selector]
Out[57]:
C1 C2 R1 0.0 4.0 R2 1.0 5.0 R3 2.0 6.0 R4 3.0 7.0
|
많은 도움 되었기를 바랍니다.