이번 포스팅에서는 Python pandas DataFrmae에서 filter() 함수를 사용하여 특정 조건에 맞는 칼럼이나 행을 선택해서 가져오는 방법을 소개하겠습니다. 

 

(1) pd.DataFrame.filter() 함수의 items 옵션을 사용하여 '이름'으로 행이나 열을 선택해서 가져오기 

(2) pd.DataFrame.filter() 함수의 regex 옵션을 사용하여 '정규 표현식'으로 행이나 열을 선택해서 가져오기

(3) pd.DataFrame.filter() 함수의 like 옵션을 사용하여 '특정 문자를 포함'하는 행이나 열을 선택해서 가져오기

 

 

pandas.DataFrame.filter()

 

 

먼저 예제로 사용할 간단한 DataFrame을 만들어보겠습니다. 

 

## sample pandas DataFrame

import numpy as np
import pandas as pd

df = pd.DataFrame(
    np.arange(12).reshape(3, 4), 
    index=['abc', 'bbb', 'ccc'], 
    columns=['x_1', 'x_2', 'var1', 'var2'])
    

df

#      x_1  x_2  var1  var2
# abc    0    1     2     3
# bbb    4    5     6     7
# ccc    8    9    10    11

 

 

 

(1) pd.DataFrame.filter() 함수의 items 옵션을 사용하여 '이름'으로 행이나 열을 선택해서 가져오기

 

(1-1) pd.DataFrame.filter(items = ['칼럼 이름 1', '칼럼 이름 2', ...], axis=1) 옵션을 사용해서 '특정 칼럼 이름'의 데이터를 선택해서 가져올 수 있습니다. 칼럼 이름은 리스트 형태 (list-like) 로 나열해줍니다. axis 의 디폴트 옵션은 axis = 1 로서 칼럼 기준입니다. 

참고로, 일상적으로 많이 사용하는 df[['칼럼 이름 1', '칼럼 이름 2', ...]] 와 같습니다.  

 

## pd.DataFrame.filter()
## : Subset the dataframe rows or columns according to the specified index labels.
## reference: https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.filter.html

## (1-1) items: select columns by name
## equivalently: df[['x_1', 'var2']]
df.filter(items=['x_1', 'var2'], axis=1)

#      x_1  var2
# abc    0     3
# bbb    4     7
# ccc    8    11

 

 

 

(1-2) pd.DataFrame.filter(items = ['열 이름 1', '열 이름 2', ...], axis=0) 옵션을 사용해서 '특정 열 이름'의 데이터를 선택해서 가져올 수 있습니다. 

참고로, 자주 사용하는 df.loc[['열 이름 1', '열 이름 2', ...]] 와 같습니다. 

 

## (1-2) items: select rows by name
## equivalently: df.loc[['bbb', 'abc']]
df.filter(items=['bbb', 'abc'], axis=0)

#      x_1  x_2  var1  var2
# bbb    4    5     6     7
# abc    0    1     2     3

 

 

 

(2) pd.DataFrame.filter() 함수의 regex 옵션을 사용하여 '정규 표현식'으로 행이나 열을 선택해서 가져오기

 

DataFrame.filter() 함수의 힘은 정규 표현식(regular expression)을 사용해서 행이나 열을 선택할 수 있다는 점입니다. 정규 표현식은 너무 광범위해서 이 포스팅에서 세부적으로 다루기에는 무리구요, 아래에는 정규 표현식의 강력함에 대한 맛보기로 세 개의 예시를 준비해봤습니다. 

 

 

(2-1) 정규 표현식을 이용해서 특정 문자로 시작(^)하는 모든 칼럼 선택해서 가져오기: regex='^(특정문자).+'

 

## (2) select columns by regular expression
## (2-1) 'x_' 로 시작하는 모든 칼럼 선택
## 캐럿 기호 ^는 텍스트의 시작, 
df.filter(regex='^(x_).+', axis=1)

#      x_1  x_2
# abc    0    1
# bbb    4    5
# ccc    8    9

 

 

(2-2) 정규 표현식을 이용해서 특정 문자로 끝나는($) 모든 칼럼 선택해서 가져오기: regex='특정문자$'

 

## (2-2) '2' 루 끝나는 모든 칼럼 선택
## 달러 기호 $는 텍스트의 끝
df.filter(regex='2$', axis=1)

#      x_2  var2
# abc    1     3
# bbb    5     7
# ccc    9    11

 

 

(2-3) 정규 표현식을 이용해서 특정 문자로 시작하지 않는 모든 칼럼 선택해서 가져오기: regex='^(?!특정문자).+'

 

## (2-3) 'x_' 로 시작하지 않는 모든 칼럼 선택
df.filter(regex='^(?!x_).+', axis=1)

#      var1  var2
# abc     2     3
# bbb     6     7
# ccc    10    11

 

 

(2-4) 정규 표현식을 이용해서 행 이름의 끝에 특정 문자를 포함하는 행(row)을 선택하기
            : DataFrame.filter(regex='특정문자$', axis=0)

 

## select rows(axis=0) containing 'c' at the end using regular expression.
df.filter(regex='c$', axis=0)

#      x_1  x_2  var1  var2
# abc    0    1     2     3
# ccc    8    9    10    11

 

 

 

(3) pd.DataFrame.filter() 함수의 like 옵션을 사용하여 '특정 문자를 포함'하는 행이나 열을 선택해서 가져오기

 

(3-1) 특정 문자를 포함하는 칼럼(column)을 선택해서 가져오기: df.filter(like='특정 문자', axis=1)

 

## (3) filter(like) 
## select columns(axis=1) containing 'x_'
df.filter(like='x_', axis=1)

#      x_1  x_2
# abc    0    1
# bbb    4    5
# ccc    8    9

 

 

(3-2) 특정 문자를 포함하는 행(row)을 선택해서 가져오기: df.filter(like='문정 문자', axis=0)

 

## select rows(axis=0) containing 'b' in a string
df.filter(like='b', axis=0)

#      x_1  x_2  var1  var2
# abc    0    1     2     3
# bbb    4    5     6     7

 

 

[Reference]

pandas.DataFrame.filter(): https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.filter.html

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!  :-)

 

728x90
반응형
Posted by Rfriend
,

Python pandas의 DataFrame은 특이하고 재미있게도 두 개 이상의 MultiIndex Column 을 가지는 DataFrame 도 지원합니다. R의 DataFrame 이나 DB의 Table 에서는 칼럼이라고 하면 당연히 1개 layer의 칼럼들만을 지원하기에, Python pandas의 2개 이상 layer의 칼럼들을 가진 DataFrame 이 처음에는 생소하고 재미있게 보였습니다. 

 

이번 포스팅에서는 Python pandas DataFrame 중에서 두 개의 MultiIndex Column 을 가지는 DataFrame 에 대해서, 이중 한개 layer의 칼럼을 기준으로 Stacking을 해서 wide-format 을 long-format으로 DataFrame을 재구조화 해보겠습니다.

 

 

reshaping pandas DataFrame with MultiIndex Column by Stacking

 

(1) csv 파일을 읽어와서 MultiIndex Column을 가진 pandas DataFrame 으로 만들기

(2) MultiIndex Column 의 Level에 이름 부여하기

(3) MultiIndex Column DataFrame의 특정 Level을 Stacking 해서 Long-format 으로 재구조화 하기

(4) 재구조화한 DataFrame의 Index 를 칼럼으로 재설정하고 정렬하기

 

 

위의 순서대로 간단한 샘플 데이터를 가지고 예를 들어보겠습니다. 

 

 

(1) csv 파일을 읽어와서 MultiIndex Column을 가진 pandas DataFrame 으로 만들기

 

아래에 첨부한 dataset.csv 파일을  pandas 의 read_csv() 메소드로 csv 파일을 읽어와서 DataFrame으로 만들 때 header=[0, 1] 옵션을 지정해줌으로써 ==> 첫번째와 두번째 행을 MultiIndex Column 으로 해서 DataFrame을 만들 수 있습니다. 

 

dataset.csv
0.00MB

## 참고로, dataset.csv 파일에는 아래 샘플 데이터가 들어있습니다.

g1,g1,g1,g2,g2,g2
c1,c2,c3,c1,c2,c3
1,2,3,4,5,6
7,8,9,10,11,12
13,14,15,16,17,18

import pandas as pd

## reading csv file with multi-column index
df = pd.read_csv('dataset.csv', header=[0, 1])

print(df)

#    g1          g2        
#    c1  c2  c3  c1  c2  c3
# 0   1   2   3   4   5   6
# 1   7   8   9  10  11  12
# 2  13  14  15  16  17  18


## MultiIndex Columns
df.columns

# MultiIndex([('g1', 'c1'),
#             ('g1', 'c2'),
#             ('g1', 'c3'),
#             ('g2', 'c1'),
#             ('g2', 'c2'),
#             ('g2', 'c3')],
#            )

 

 

 

(2) MultiIndex Column 의 Level에 이름 부여하기

 

MultiIndex Column의 Level 에 접근할 때 "위치(position)"로 할 수도 있고, 혹은 Level에 이름을 부여(rename)해서 "이름(name)"을 기준으로 접근할 수도 있습니다. 

 

rename() 메소드를 사용해서 이번 예제의 MultiIndex Column의 첫번째 Level에는 'grp_nm' 이라는 이름을, 두번째 Level 에는 'col_nm' 이라는 이름을 부여해보겠습니다. 

 

## renaming multi-column index
df.columns.rename(['grp_nm', 'col_nm'], inplace=True)


print(df)

# grp_nm  g1          g2        
# col_nm  c1  c2  c3  c1  c2  c3
# 0        1   2   3   4   5   6
# 1        7   8   9  10  11  12
# 2       13  14  15  16  17  18


df.columns

# MultiIndex([('g1', 'c1'),
#             ('g1', 'c2'),
#             ('g1', 'c3'),
#             ('g2', 'c1'),
#             ('g2', 'c2'),
#             ('g2', 'c3')],
#            names=['grp_nm', 'col_nm'])  # <== now, names of MultiIndex levels

 

 

 

(3) MultiIndex Column DataFrame의 특정 Level을 Stacking 해서 Long-format 으로 재구조화 하기

 

위의 (2)번에서 MultiIndex Column의 첫번째 Level 에 'grp_nm' 이라는 이름을 부여했는데요, 이번에는 'grp_nm' 이름의 Level 을 기준으로 stack() 메소드를 사용해서 wide-format 을 long-format 의 DataFrame으로 재구조화(reshaping) 해보겠습니다. 

 

이렇게 stacking을 해서 재구조화하면 MultiIndex Column DataFrame 이 (우리가 익숙하게 사용하는) SingleIndex Column의 DataFrame으로 바뀌게 되며, ==> 이제 'grp_nm'은 Index 로 들어가 있습니다. 

 

## reshaping DataFrame from MultiIndex Column from SingleIndex long-format by stacking

df_stacked = df.stack(level='grp_nm')

print(df_stacked)

# col_nm    c1  c2  c3
#   grp_nm            
# 0 g1       1   2   3
#   g2       4   5   6
# 1 g1       7   8   9
#   g2      10  11  12
# 2 g1      13  14  15
#   g2      16  17  18

 

 

 

(4) 재구조화한 DataFrame의 Index 를 칼럼으로 재설정하고 정렬하기

 

마지막으로, MultiIndex Column 의 첫번째 Level 을 Stacking 하고 난 후 Index로 사용된 'grp_nm' 을 reset_index() 메소드를 사용해서 칼럼으로 재설정하고, ==> 가시성을 높일 수 있도록 sort_values(by=['grp_nm']) 을 사용해서 'grp_nm' 칼럼을 기준으로 오름차순 정렬을 해보겠습니다. 

 

## reset index and sorting by column
df_stacked_sorted = df.stack(level='grp_nm').reset_index(['grp_nm']).sort_values(by=['grp_nm'])


print(df_stacked_sorted)

# col_nm grp_nm  c1  c2  c3
# 0          g1   1   2   3
# 1          g1   7   8   9
# 2          g1  13  14  15
# 0          g2   4   5   6
# 1          g2  10  11  12
# 2          g2  16  17  18

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요! :-)

 

728x90
반응형
Posted by Rfriend
,

예전 포스팅(https://rfriend.tistory.com/250)에서 pandas read_csv() 함수로 text, csv 파일을 읽어오는 방법을 소개하였습니다. 


이번 포스팅에서는 Python pandas의 read_csv() 함수를 사용하여 csv file, text file 을 읽어와 DataFrame을 만들 때 날짜/시간 (Date/Time) 이 포함되어 있을 경우 이를 날짜/시간 형태(DateTime format)에 맞도록 파싱하여 읽어오는 방법을 소개하겠습니다. 


[예제 샘플 데이터] 

date_sample






  (1) 날짜/시간 포맷 지정 없이 pd.read_csv() 로 날짜/시간 데이터 읽어올 경우


예제로 사용할 데이터는 위의 이미지 우측 상단에 있는 바와 같이 '1/5/2020 10:00:00' (1일/ 5월/ 2020년 10시:00분:00초) 형태의 날짜/시간 칼럼을 포함하고 있는 텍스트 파일입니다. 


이 예제 데이터를 날짜/시간 포맷에 대한 명시적인 설정없이 그냥 pandas의 read_csv() 함수로 읽어와서 DataFrame을 만들 경우 아래와 같이 object 데이터 형태로 불어오게 됩니다. 이럴 경우 별도로 문자열을 DateTime foramt으로 변환을 해주어야 하는 불편함이 있습니다. (참고: https://rfriend.tistory.com/498)



import pandas as pd


df = pd.read_csv('date_sample', sep=",", names=['date', 'id', 'val']) # no datetime parsing


df

dateidval
01/5/2020 10:00:00110
11/5/2020 10:10:00112
21/5/2020 10:20:00117
31/5/2020 10:00:00211
41/5/2020 10:10:00214
51/5/2020 10:20:00216


df.info()

<class 'pandas.core.frame.DataFrame'> RangeIndex: 6 entries, 0 to 5 Data columns (total 3 columns): date 6 non-null object <-- not datetime format id 6 non-null int64 val 6 non-null int64 dtypes: int64(2), object(1) memory usage: 272.0+ bytes




-- 날짜/시간 파싱 자동 추정 --

  (2) parse_dates=['date'] 칼럼에 대해 

      dayfirst=True 일이 월보다 먼저 위치하는 것으로 

      infer_datetime_format=True 날짜시간 포맷 추정해서 파싱하기


이번 예제 데이터의 경우 '1/5/2020 10:00:00' (1일/ 5월/ 2020년 10시:00분:00초) 처럼 '일(day)'이 '월(month)' 보다 먼저 나오으므로 dayfirst=True 로 설정해주었습니다. infer_datetime_format=True 로 설정해주면 Python pandas가 똑똑하게도 알아서 날짜/시간 포맷을 추정해서 잘 파싱해줍니다. 




df_date.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 3 columns):
date    6 non-null datetime64[ns] <-- datetime foramt!!
id      6 non-null int64
val     6 non-null int64
dtypes: datetime64[ns](1), int64(2)
memory usage: 272.0 bytes



import pandas as pd


df_date = pd.read_csv("date_sample", 

                      sep=",", 

                      names=['date', 'id', 'val'], 

                      parse_dates=['date']

                      dayfirst=True, # May 1st

                      infer_datetime_format=True)



df_date  # May 1st, 2020

dateidval
02020-05-01 10:00:00110
12020-05-01 10:10:00112
22020-05-01 10:20:00117
32020-05-01 10:00:00211
42020-05-01 10:10:00214
52020-05-01 10:20:00216




  (3) dayfirst=False 일(day)이 월(month)보다 뒤에 있는 파일 날짜/시간 파싱하기


만약에 '1/5/2020 10:00:00' (1월/ 5일/ 2020년 10시:00분:00초) 의 형태로 월(month)이 일(day)보다 먼저 나오는 파일을 읽어와서 파싱하는 경우에는 dayfirst=False 로 설정해주면 됩니다. (default 값은 False 이므로 생략 가능합니다)



df_date_dayfirstF = pd.read_csv("date_sample", 

                                sep=",", 

                                names=['date', 'id', 'val'], 

                                parse_dates=['date']

                                dayfirst=False, # January 5th, default setting

                                infer_datetime_format=True)



df_date_dayfirstF  # January 5th, 2020

dateidval
02020-01-05 10:00:00110
12020-01-05 10:10:00112
22020-01-05 10:20:00117
32020-01-05 10:00:00211
42020-01-05 10:10:00214
52020-01-05 10:20:00216

 




-- 날짜/시간 파싱 함수 수동 지정 --

  (4) date_parser=Parser 함수를 사용해서 데이터 읽어올 때 날짜/시간 파싱하기


위의 (2)번, (3)번에서는 infer_datetime_format=True 로 설정해줘서 pandas가 알아서 날짜/시간 포맷을 추정(infer)해서 파싱을 해주었다면요, 


이번에는 날짜/시간 파싱하는 포맷을 lambda 함수로 직접 명시적으로 사용자가 지정을 해주어서 read_csv() 함수로 파일을 읽어올 때 이 함수를 사용하여 날짜/시간 포맷을 파싱하는 방법입니다. 

이번 예제의 날짜/시간 포맷에 맞추어서 datetime.strptime(x, "%d/%m/%Y %H:%M:%S") 로 string을 datetime으로 변환해주도록 하였습니다. 



# parsing datetime string using lambda Function at date_parser

# Reference: converting string to DataTime: https://rfriend.tistory.com/498

import pandas as pd

from datetime import datetime


dt_parser = lambda x: datetime.strptime(x, "%d/%m/%Y %H:%M:%S")


df_date2 = pd.read_csv("date_sample", 

                       sep=",", 

                       names=['date', 'id', 'val'], 

                       parse_dates=['date'], # column name

                       date_parser=dt_parser)


df_date2

dateidval
02020-05-01 10:00:00110
12020-05-01 10:10:00112
22020-05-01 10:20:00117
32020-05-01 10:00:00211
42020-05-01 10:10:00214
52020-05-01 10:20:00216




참고로, pd.read_csv() 함수에서 날짜/시간 데이터는 위에서 처럼 parse_dates=['date'] 처럼 명시적으로 칼럼 이름을 설정해줘도 되구요, 아래처럼 parse_dates=[0] 처럼 위치 index 를 써주어도 됩니다. 



# parse_dates=[column_position]

import pandas as pd

from datetime import datetime


dt_parser = lambda x: datetime.strptime(x, "%d/%m/%Y %H:%M:%S")

df_date3 = pd.read_csv("date_sample", 

                       sep=",", 

                       names=['date', 'id', 'val'], 

                       parse_dates=[0], # position index

                       date_parser=dt_parser)


df_date3

dateidval
02020-05-01 10:00:00110
12020-05-01 10:10:00112
22020-05-01 10:20:00117
32020-05-01 10:00:00211
42020-05-01 10:10:00214
52020-05-01 10:20:00216





  (5) index_col 로 날짜-시간 데이터를 DataFrame index로 불러오기


마지막으로, 파일을 읽어올 때 index_col=['column_name'] 또는 index_col=column_position 을 설정해주면 날짜/시간을 pandas DataFrame의 index로 바로 읽어올 수 있습니다. 

(그냥 칼럼으로 읽어온 후에 date 칼럼을 reindex() 를 사용해서 index로 설정해도 됩니다. 

 * 참고: https://rfriend.tistory.com/255)



# use datetime as an index

import pandas as pd


df_date_idx = pd.read_csv("date_sample", 

                          sep=",", 

                          names=['date', 'id', 'val'], 

                          index_col=['date'], # or index_col=0 

                          parse_dates=True, 

                          dayfirst=True,

                          infer_datetime_format=True)



df_date_idx

idval
date
2020-05-01 10:00:00110
2020-05-01 10:10:00112
2020-05-01 10:20:00117
2020-05-01 10:00:00211
2020-05-01 10:10:00214
2020-05-01 10:20:00216




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

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


728x90
반응형
Posted by Rfriend
,

Python 을 가지고 분석에 활용한다고 했을 때 데이터 전처리에 NumPy와 pandas library를 많이 사용합니다.  특히, 행과 열로 구성이 되어있는 DataFrame type 데이터를 입력, 처리, 조작할 때 pandas 가 매우 강력하고 편리합니다.

 

 

Python의 pandas library의 read_csv() 함수를 사용해서 외부 text 파일, csv 파일을 불러와서 DataFrame으로 저장하는 방법에 대해서 소개하겠습니다.

 

 

 1. csv 파일 불러오기 : read_csv()

 

 

아래와 같이 ID, LAST_NAME, AGE 3개의 열(column)을 가지고 있고, 5개의 행(row) 가지고 있는, 콤마로 구분된 CSV 파일(comma sepeated file)을 예제로 사용하겠습니다.

 

[예제 CSV 파일 : test_csv_file.csv => test_csv_file.csv   ]

 

ID

LAST_NAME

AGE

1

KIM

30

2

CHOI

25

3

LEE

41

4

PARK

19

5

LIM

36

 

 

import 로 pandas library를 호출한 다음에 read_csv() 함수에 파일 경로파일 이름을 적어주면 됩니다. csv 파일은 구분자(separator, delimiter)를 명시적으로 ',' (comma)라고 지정해주지 않아도 알아서 잘 불러옵니다.

 

 

>>> import pandas as pd
>>> csv_test = pd.read_csv('C:/Users/Administrator/Documents/Python/test_csv_file.csv')

 

 

 

 

DataFrame.shape 을 사용해서 행(row)과 열(column)의 개수를 확인해보고, 행과 열이 몇 개 안되므로 indexing 없이 전체를 호출해보겠습니다.

 

 

>>> csv_test.shape # number of rows, columns
(5, 3)
>>> csv_test 
   ID LAST_NAME  AGE
0   1       KIM   30
1   2      CHOI   25
2   3       LEE   41
3   4      PARK   19
4   5       LIM   36

 

 

 

 

Spyder (Python 3.5) 의 'Variable explorer' 창에 보면 csv 라는 이름의 DataFrame 이 신규로 생성되었으며, Size 란에 보면 (5, 3) 으로서 5개 행(rows), 3개 열(columns)으로 구성되어 있음을 알 수 있습니다.

 

csv DataFrame 이름을 클릭하면 아래 그림처럼 행과 열로 구성된 2차원이 DataFrame을 열어서 볼 수 있습니다.

 

 

 

 

 

 2. 구분자 '|' 인 text 파일 불러오기 : sep='|'

 

이번에는 구분자가 콤마(,)가 아닌 다른 기호, 가령, 수직 막대기 '|' 인 경우의 text 파일을 불러와보도록 하겠습니다. 

 

[ 예제 test_text_file.txt  => test_text_file.txt   ]

ID|A|B|C|D
C1|1|2|3|4
C2|5|6|7|8
C3|1|3|5|7

 

 

 

read_csv() 함수는 동일하며, 파일 경로와 text 파일 이름을 써주고, 구분자(separator, delimiter)에 sep='|' 를 추가해줍니다.

 

 

>>> text_test = pd.read_csv('C:/Users/Administrator/Documents/Python/test_text_file.txt', sep='|')
>>> text_test
   ID  A  B  C  D
0  C1  1  2  3  4
1  C2  5  6  7  8
2  C3  1  3  5  7

 

 


만약 구분자가 탭(tab) 이라면 sep = '\t' 을 입력해줍니다.  



 

 3. 파일 불러올 때 index 지정해주기 : index_col

 

 

만약에 위의 예에서 첫번째 열인 'ID'라는 이름의 변수를 Index 로 지정해주고 싶으면 index_col=0 (위치)이나 index_col='ID' 처럼 직접 변수 이름을 지정해주면 됩니다.

 

 

>>> # pass the column number you wish to use as the index:
... pd.read_csv('C:/Users/Administrator/Documents/Python/test_text_file.txt', sep='|', index_col=0)
    A  B  C  D
ID           
C1  1  2  3  4
C2  5  6  7  8
C3  1  3  5  7

 

 

 

>>> # pass the column name you wish to use as the index:
... pd.read_csv('C:/Users/Administrator/Documents/Python/test_text_file.txt', sep='|', index_col='ID')
    A  B  C  D
ID           
C1  1  2  3  4
C2  5  6  7  8
C3  1  3  5  7

 

 

 

 

 

 4. 변수 이름(column name, header) 이 없는 파일 불러올 때 이름 부여하기

     : names=['X1', 'X2', ... ], header=None

 

 

[ 예제 : 변수 이름이 없는 text 파일(no header)  =>  text_without_column_name.txt ]

 

C1|1|2|3|4
C2|5|6|7|8
C3|1|3|5|7

 

 

names=['ID', 'A', 'B', 'C', 'D'] 와 같이 칼럼 이름을 부여해줍니다.  header=None 은 칼럼 이름이 없다는 뜻이며, 만약 1번째 행이 칼럼 이름이라면 header=0 으로 지정해주면 됩니다.

 

 

>>> # naming columns :
... pd.read_csv('C:/Users/Administrator/Documents/Python/text_without_column_name.txt', sep='|', names=['ID', 'A', 'B', 'C', 'D'], header=None, index_col='ID')
    A  B  C  D
ID           
C1  1  2  3  4
C2  5  6  7  8
C3  1  3  5  7

 

 

 

 

 5. 유니코드 디코드 에러, UnicodeDecodeError: 'utf-8' codec can't decode byte

 

불러오려는 text, csv 파일의 encoding 설정과 Python encoding 설정이 서로 맞지 않으면 UnicodeDecodeError 가 발생합니다.  한글은 보통 'utf-8' 을 많이 사용하는데요, 만약 아래처럼 'utf-8' 코덱을 decode 할 수 없다고 에러 메시지가 나오는 경우가 있습니다.

 

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 26: invalid start byte 

이럴 경우에는 Windows에서 많이 사용하는 'CP949'로 아래처럼 encoding을 설정해서 text, csv 파일 불러오기를 해보시기 바랍니다.

 

 

f = pd.read_csv('directory/file', sep='|'', encoding='CP949')

 

 


혹시 encoding='CP949' 로 해도 안되면 encoding='latin' ('ISO-8859-1' 의 alias) 도 한번 시도해보시기 바랍니다. 


f = pd.read_csv('directory/file', sep='|'', encoding='latin')

 


코덱을 모두 설명하기에는 너무 양이 많으므로 이하 생략합니다.



 6. 특정 줄은 제외하고 불러오기: skiprows = [x, x]


skip rows 옵션을 사용하여 첫번째와 두번째 줄은 제외하고 csv 파일을 DataFrame으로 불러와보겠습니다. 



# skip 1st and 2nd rows (do not read 1, 2 rows)

csv_2 = pd.read_csv("C:/Users/admin/Documents/data/test_csv_file.csv", 

                           skiprows = [1, 2])  







 7. n 개의 행만 불러오기: nrows = n


csv 파일의 위에서 부터 3개의 행(rows) 만 DataFrame으로 불어와보겠습니다. 


 

# read top 3 rows only

csv_3 = pd.read_csv("C:/Users/admin/Documents/data/test_csv_file.csv", 

                    nrows = 3)







  8. 사용자 정의 결측값 기호 (custom missing value symbols) 


불러오려는 데이터셋 파일에 다양한 모양, 기호의 결측값이 들어있을 수 있습니다. 이때 사용자 정의 결측값 기호를 표기해줌으로써 이들 특정 기호를 pandas가 결측값으로 인식할 수 있도록 해줍니다. 가령  어떤 문서에 숫자형 변수에 결측값이 '??'라는 표시로 입력이 되어있다고 한다면, 이를 pandas DataFrame으로 불러읽어들였을 경우 float나 int로 인식되어 불러오는 것이 아니라 string으로 인식해서 '??'를 결측값이 아니라 문자형으로 불러오게 됩니다. 이럴 경우 '??'를 결측값이라고 인식하라고 알려주는 역할이 na_values = ['??'] 옵션입니다. 



df = pd.read_csv('C:/Users/Administrator/Documents/Python/test_text_file.txt', 

                             na_values = ['?', '??', 'N/A', 'NA', 'nan', 'NaN', '-nan', '-NaN', 'null')

 


물론 데이터를 읽어들인 후에 후행적으로 결측값으로 인식되어야 할 것들(예: '?', 'N/A' 등)이 문자열로 잘못 인식되어 잘못 불어와졌을 경우 pandas의 데이터변환 함수를 사용해서 전처리할 수도 있습다만, 자칫 결측값이 있는 줄도 모르고 결측값 처리를 안하고 다음번 분석으로 넘어갈 실수를 할 수도 있으므로 가급적 데이터를 불러오는 단계에서 결측값 기호를 사전에 파악하시고 '사용자 정의 결측값 기호 na_values = [] 옵션'을 사용해서 결측값으로 인식해서 불러오는 것이 가장 좋은 방법이라고 생각합니다. 



  9. 데이터 유형 설정 (Setting the data type per each column)


pandas는 데이터셋을 읽어들일 때 첫번째 행의 데이터를 기준으로 각 칼럼별 데이터 유형을 추정해서 자동으로 세팅을 해줍니다. 대부분의 경우는 잘 맞는 편인데요, 가끔 분석가가 의도한 데이터유형으로 설정되지 않는 경우도 있습니다.(가령, 위의 8번 결측값 기호를 string object로 잘못 인식한다든지...)  DB 사용자라면 데이터 유형을 명시적으로 설정해주는 것에 익숙하실 텐데요, pandas의 pd.read_csv()에도 사용자가 dtpye 옵션으로 사전형(dictionary)으로 각 칼럼(key) 별 데이터 유형(value)를 짝을 지어서 명시적으로 설정해 줄 수 있습니다. 


df = pd.read_csv('C:/Users/Administrator/Documents/Python/test_text_file.txt', 

                            dtype = {"ID": int, 

                                          "LAST_NAME": str, 

                                          "AGE": float}

                            )

 



날짜/시간 형태(date/time format)의 데이터의 경우 infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates 등의 시계열 데이터 형태에 특화된 옵션들이 있습니다. 자세한 내용은 아래의 pandas 매뉴얼을 참고하시기 바랍니다. 언제 시간이 되면 시계열데이터 전처리 및 분석은 별도의 세션으로 여러차례 연재를 해보겠습니다. 




Python pandas 라이브러리의 read_csv() 함수를 이용한 text, csv 파일 불러오기 소개를 마치겠습니다.

 

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

 

 


728x90
반응형
Posted by Rfriend
,