Professional Documents
Culture Documents
7. 자료 준비 및 손질
7. 자료 준비 및 손질
자료 준비 및 손질
자료 분석 및 모델링 작업 시간 중 80% 이상이 자료 준비에 소모된다. 자료 준비란 읽어오기, 정
제, 변환, 정렬등을 말한다. 파일 또는 데이터베이스 자료는 특정 작업을 하는데 적당한 형태가
아닌 경우가 많다. 많은 개발자들은 하나의 형태로부터 다른 형태의 자료로 변경하기 위해 파
이썬, 자바, C 등 프로그래밍 언어를 사용하기도 한다. 판다스는 파이썬 내장 기능들을 포함하
면서 고수준, 유연하고, 빠르게 적당한 형태로 변경을 할 수 있는 기능들을 제공한다.
소실 자료 다루기
자료 분석 과정에서 소실값은 흔하게 일어난다. 판다스는 소실값에 대해서 어려움을 당하지 않
게 다루도록 하려고 하고 있다. 예를 들면 판다스는 기술 통계량을 구할 때 기본적으로 소실값
을 제외하고 계산을 한다.
Out[197]: 0 아보카도
1 아리랑
2 NaN
3 아리아
dtype: object
In [198]: 문.isnull()
Out[198]: 0 False
1 False
2 True
3 False
dtype: bool
Argument Description
dropna Filter axis labels based on whether values for each label have missing data, with v
fillna Fill in missing data with some value or using an interpolation method such as ‘ffil
소실값 걸러내기
Out[200]: 0 1.3
1 NaN
2 9.0
3 -20.0
4 NaN
dtype: float64
In [201]: 시.dropna()
Out[201]: 0 1.3
2 9.0
3 -20.0
dtype: float64
In [202]: 시[시.notnull()]
Out[202]: 0 1.3
2 9.0
3 -20.0
dtype: float64
In [203]: 데 = pd.DataFrame([[1., 3.5, 2.2], [1., np.nan, np.nan], [np.nan, np.nan, np.nan],
[np.nan, 6.5, 3.0]])
데
Out[203]:
0 1 2
0 1.0 3.5 2.2
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
In [204]: 데.dropna()
Out[204]:
0 1 2
0 1.0 3.5 2.2
In [205]: 데.dropna(how='all')
Out[205]:
0 1 2
0 1.0 3.5 2.2
1 1.0 NaN NaN
3 NaN 6.5 3.0
Out[206]:
0 1 32
0 1.0 3.5 2.2 NaN
1 1.0 NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN 6.5 3.0 NaN
Out[207]:
0 1 2
0 1.0 3.5 2.2
1 1.0 NaN NaN
2 NaN NaN NaN
3 NaN 6.5 3.0
thresh= 인자를 사용해서 원하는 갯수의 NA들을 포함하는 행들만 삭제할 수 있다.
In [209]: 데.dropna(thresh=2)
Out[209]:
0 1 2
2 -0.066663 NaN -0.791498
3 0.023971 NaN 1.020213
4 1.346790 0.257321 0.608375
5 1.199808 -0.483835 -0.159827
6 -0.168269 0.771990 0.245259
소실값 채우기
In [210]: 데.fillna(0)
Out[210]:
0 1 2
0 0.895511 0.000000 0.000000
1 -0.484012 0.000000 0.000000
2 -0.066663 0.000000 -0.791498
3 0.023971 0.000000 1.020213
4 1.346790 0.257321 0.608375
5 1.199808 -0.483835 -0.159827
6 -0.168269 0.771990 0.245259
Out[211]:
0 1 2
0 0.895511 0.000000 0.500000
1 -0.484012 0.000000 0.500000
0 1 2
2 -0.066663 0.000000 -0.791498
3 0.023971 0.000000 1.020213
4 1.346790 0.257321 0.608375
5 1.199808 -0.483835 -0.159827
6 -0.168269 0.771990 0.245259
Out[212]:
0 1 2
0 0.895511 0.000000 0.500000
1 -0.484012 0.000000 0.500000
2 -0.066663 0.000000 -0.791498
3 0.023971 0.000000 1.020213
4 1.346790 0.257321 0.608375
5 1.199808 -0.483835 -0.159827
6 -0.168269 0.771990 0.245259
Out[213]:
0 1 2
0 0.828091 -1.068962 -1.113197
1 -0.033009 -0.339193 -0.334388
2 1.601875 NaN -1.205323
3 0.373438 NaN 0.095143
4 -0.035278 NaN NaN
5 -0.941367 NaN NaN
In [214]: 프.fillna(method='ffill')
Out[214]:
0 1 2
0 0.828091 -1.068962 -1.113197
1 -0.033009 -0.339193 -0.334388
2 1.601875 -0.339193 -1.205323
3 0.373438 -0.339193 0.095143
4 -0.035278 -0.339193 0.095143
5 -0.941367 -0.339193 0.095143
Out[215]:
0 1 2
0 0.828091 -1.068962 -1.113197
1 -0.033009 -0.339193 -0.334388
2 1.601875 -0.339193 -1.205323
3 0.373438 -0.339193 0.095143
4 -0.035278 NaN 0.095143
5 -0.941367 NaN 0.095143
Out[216]: 0 NaN
1 -1.50
2 NaN
3 3.00
4 2.54
dtype: float64
In [217]: 시.fillna(시.mean())
Out[217]: 0 1.346667
1 -1.500000
2 1.346667
3 3.000000
4 2.540000
dtype: float64
In [218]: 시.fillna(시.median())
Out[218]: 0 2.54
1 -1.50
2 2.54
3 3.00
4 2.54
dtype: float64
Argument Description
limit For forward and backward filling, maximum number of consecutive periods to fil
자료 변환
중복 제거
Out[219]:
k1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4
6 two 4
In [220]: 데.duplicated()
Out[220]: 0 False
1 False
2 False
3 False
4 False
5 False
6 True
dtype: bool
직접하기
In [221]: 데.drop_duplicates()
Out[221]:
k1 k2
0 one 1
1 two 1
2 one 2
3 two 3
4 one 3
5 two 4
Out[222]:
k1 k2 v1
0 one 1 0
1 two 1 1
2 one 2 2
3 two 3 3
4 one 3 4
5 two 4 5
6 two 4 6
In [223]: 데.drop_duplicates(['k1'])
Out[223]:
k1 k2 v1
0 one 1 0
1 two 1 1
Out[224]:
k1 k2 v1
0 one 1 0
1 two 1 1
2 one 2 2
3 two 3 3
4 one 3 4
6 two 4 6
함수 또는 대응을 이용한 자료 변환
Out[225]:
food ounces
0 bacon 4.0
1 pulled pork 3.0
2 bacon 12.0
3 Pastrami 6.0
4 corned beef 7.5
food ounces
5 Bacon 8.0
6 pastrami 3.0
7 honey ham 5.0
8 nova lox 6.0
In [226]: meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
호출자.map(함수)
Out[227]: 0 bacon
1 pulled pork
2 bacon
3 pastrami
4 corned beef
5 bacon
6 pastrami
7 honey ham
8 nova lox
Name: food, dtype: object
Out[228]:
food ounces animal
0 bacon 4.0 pig
1 pulled pork 3.0 pig
2 bacon 12.0 pig
3 Pastrami 6.0 cow
food ounces animal
4 corned beef 7.5 cow
5 Bacon 8.0 pig
6 pastrami 3.0 cow
7 honey ham 5.0 pig
8 nova lox 6.0 salmon
Out[229]: 0 pig
1 pig
2 pig
3 cow
4 cow
5 pig
6 cow
7 pig
8 salmon
Name: food, dtype: object
값 대체하기
Out[230]: 0 1.0
1 -999.0
2 2.0
3 -999.0
4 -1000.0
5 -3.0
dtype: float64
Out[231]: 0 1.0
1 NaN
2 2.0
3 NaN
4 -1000.0
5 -3.0
dtype: float64
Out[232]: 0 1.0
1 NaN
2 2.0
3 NaN
4 NaN
5 -3.0
dtype: float64
Out[233]: 0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 -3.0
dtype: float64
Out[234]: 0 1.0
1 NaN
2 2.0
3 NaN
4 0.0
5 -3.0
dtype: float64
축 인덱스 이름 변경하기
Out[235]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
데.index.map(트)
Out[237]:
one two three four
OHIO 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11
Out[238]:
ONE TWO THREE FOUR
Ohio 0 1 2 3
Colo 4 5 6 7
New 8 9 10 11
Out[239]:
one two peekaboo four
INDIANA 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11
Out[240]:
one two three four
INDIANA 0 1 2 3
COLO 4 5 6 7
NEW 8 9 10 11
구간으로 나누기
In [241]: 나이 = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
18 ~ 25, 26 ~ 35, 36 ~ 60 및 60세보다 많은 연령대별로 나눈다. 이렇게 하기위해서는 판다스
의 cut 함수를 사용하면 된다.
Out[242]: [(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35,
60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
In [243]: 연령대.categories
In [244]: 연령대.codes
In [245]: 연령대.value_counts()
Out[246]: [[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35,
60), [35, 60), [25, 35)]
Length: 12
Categories (4, interval[int64]): [[18, 25) < [25, 35) < [35, 60) < [60, 100)]
Out[247]: [청년, 청년, 청년, 청장년, 청년, ..., 청장년, 노년, 중년, 중년, 청장년]
Length: 12
Categories (4, object): [청년 < 청장년 < 중년 < 노년]
Out[249]: [(1.44, 2.24], (-0.17, 0.63], (0.63, 1.44], (1.44, 2.24], (1.44, 2.24], ..., (-0.17,
0.63], (1.44, 2.24], (-0.98, -0.17], (-0.17, 0.63], (-0.98, -0.17]]
Length: 20
Categories (4, interval[float64]): [(-0.98, -0.17] < (-0.17, 0.63] < (0.63, 1.44] <
(1.44, 2.24]]
cats = pd.qcut(data, 4)
cats
In [251]: pd.value_counts(cats)
이상치(outlier) 찾아 걸러내기
Out[253]:
0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean -0.036400 0.011587 -0.003675 -0.002479
std 0.992339 0.968516 0.994501 0.988656
min -3.740101 -3.007437 -3.116857 -3.392300
25% -0.760730 -0.656073 -0.671151 -0.646979
50% 0.015750 -0.012295 0.003705 -0.063378
75% 0.643699 0.656041 0.684573 0.646954
max 2.929096 2.979976 3.801660 3.427539
Out[254]:
0 1 2 3
8 -0.156024 1.049093 3.170975 0.189500
249 0.708860 0.422819 -3.116857 0.644452
515 -0.387313 -0.347585 3.306574 -1.510200
524 -1.091033 -0.126856 3.801660 2.315171
606 0.236225 -0.752582 0.045113 3.427539
610 -0.087328 -0.553965 -3.006499 -0.047166
664 -0.953179 -0.479297 -1.345508 -3.392300
683 -3.740101 0.973577 1.175155 -1.124703
862 0.903088 -3.007437 -2.330467 -0.567803
Out[255]:
0 1 2 3
count 1000.000000 1000.000000 1000.000000 1000.000000
mean -0.035660 0.011594 -0.004831 -0.002515
std 0.989846 0.968493 0.989858 0.985992
min -3.000000 -3.000000 -3.000000 -3.000000
25% -0.760730 -0.656073 -0.671151 -0.646979
50% 0.015750 -0.012295 0.003705 -0.063378
75% 0.643699 0.656041 0.684573 0.646954
max 2.929096 2.979976 3.000000 3.000000
을 이용할 수 있다. 축 크기에 해당되는 permutation 함수를 호출하면 무작위 순열이 반환된다.
iloc 또는 take 함수를 이용해서 순열에 대응되도록 배열의 행들을 배치할 수 있다.
In [257]: df
Out[257]:
0 1 2 3
00 1 2 3
14 5 6 7
2 8 9 10 11
3 12 13 14 15
4 16 17 18 19
In [258]: df.iloc[sampler]
Out[258]:
0 1 2 3
14 5 6 7
00 1 2 3
3 12 13 14 15
2 8 9 10 11
4 16 17 18 19
In [259]: df.take(sampler)
Out[259]:
0 1 2 3
14 5 6 7
00 1 2 3
3 12 13 14 15
2 8 9 10 11
4 16 17 18 19
In [260]: df.sample(3)
Out[260]:
01 2 3
2 8 9 10 11
01 2 3
0012 3
1456 7
Out[261]: 4 4
1 3
4 4
0 7
3 1
2 -2
2 -2
2 -2
2 -2
4 4
dtype: int64
Out[262]:
data1 keys
00 b
11 b
22 a
33 c
44 a
55 b
In [263]: pd.get_dummies(df['keys'])
Out[263]:
ab c
0010
1010
2100
3001
4100
5010
‘keys``열은``’a’ , ’b’ , ’c’ 로 이루어져 있고 첫번째 행은 ’b’ 이므로
Out[264]:
key_a key_b key_c
00 1 0
10 1 0
21 0 0
30 0 1
41 0 0
50 1 0
Out[265]:
id title genre
0 1 Toy Story (1995) Animation|Children's|Comedy
1 2 Jumanji (1995) Adventure|Children's|Fantasy
2 3 Grumpier Old Men (1995) Comedy|Romance
3 4 Waiting to Exhale (1995) Comedy|Drama
4 5 Father of the Bride Part II (1995) Comedy
In [266]: all_genres = []
for x in movies.genre:
all_genres.extend(x.split('|'))
genres = pd.unique(all_genres)
genres
In [269]: dummies.iloc[0]
pd.get_dummies(pd.cut(values, bins))
Out[271]:
(0.0, 0.2] (0.2, 0.4] (0.4, 0.6] (0.6, 0.8] (0.8, 1.0]
00 1 0 0 0
10 0 1 0 0
21 0 0 0 0
31 0 0 0 0
41 0 0 0 0
50 1 0 0 0
60 0 1 0 0
70 0 1 0 0
80 0 0 1 0
90 0 1 0 0
문자열 처리
문자열 객체 메소드
In [274]: "::".join(pieces)
Out[274]: 'a::b::guido'
Out[275]: True
In [276]: val.index(',')
Out[276]: 1
In [277]: val.find(':')
Out[277]: -1
Argument Description
index Return position of first character in substring if found in the string; raises
rfind Return position of first character of last occurrence of substring in the str
strip, rstrip, lstrip Trim whitespace, including newlines; equivalent to x.strip() (and rstrip, lst
ljust, rjust Left justify or right justify, respectively; pad opposite side of string with sp
정규 표현식
In [279]: import re
regex.split(text)
In [282]: regex.findall(text)
In [288]: regex.findall(text)
search 는 반환값으로 match 객체를 반환해서 다음과 같이 메소드 start , end 를 이용할 수 있
다.
In [289]: m = regex.search(text)
m
Out[289]: <_sre.SRE_Match object; span=(5, 20), match='dave@google.com'>
In [290]: text[m.start():m.end()]
Out[290]: 'dave@google.com'
찾은 이메일 문자열 중에서 사용자 이름, 하위 도메인 이름, 최상위 도메인 이름으로 구분해서
사용하고 싶을 때 소괄호를 이용할 수 있다.
m_g.groups()
group 메소드를 이용해서 각각의 성분을 접근할 수 있다. group() 는 group(0) 와 같은 것으로
유형에 일치하는 문자열을 반환한다.
In [298]: m_g.group()
Out[298]: 'dave@google.com'
In [299]: m_g.group(1)
Out[299]: 'dave'
In [300]: m_g.group(2)
Out[300]: 'google'
In [301]: m_g.group(3)
Out[301]: 'com'
findall 은 그룹을 성분으로 하는 튜플 리스트를 반환한다.
In [294]: regex_g.findall(text)
Argument Description
match Match pattern at start of string and optionally segment pattern components into
search Scan string for match to pattern; returning a match object if so; unlike match, the
sub, subn Replace all (sub) or first n occurrences (subn) of pattern in string with replaceme
직접하기
판다스 벡터 문자열 함수
data
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-304-532f4f311e25> in <module>()
----> 1 data.map(lambda x: x.count('g'))
pandas/_libs/src/inference.pyx in pandas._libs.lib.map_infer()
<ipython-input-304-532f4f311e25> in <lambda>(x)
----> 1 data.map(lambda x: x.count('g'))
Out[313]: Dave 2
Rob 1
Steve 1
dtype: int64
판다스 str 속성을 이용하면 문제없이 다루는 것을 볼 수 있다. str 속성은 각 성분을 일괄적
으로 처리할 수 있는 함수들을 제공한다. 다음은 gmail 이란 문자열을 포함하고 있는지를 판단
하는 contains 메소드를 이용한 것이다.
In [314]: data.str.contains('gmail')
Out[316]:
0 1 2
match
Dave 0 dave google com
Rob 0 rob gmail com
Steve 0 steve gmail com
Out[318]:
0 1 2
match
Dave 0 dave google com
1 dooly gmail com
Rob 0 rob gmail com
Steve 0 steve gmail com
In [320]: ser.str.get(0)
Out[320]: Dave d
Rob r
Steve s
Wes NaN
dtype: object
In [322]: ser.str[:-1]
메소드 설명
rsplit() Split strings on delimiter working from the end of the string
join() Join strings in each element of the Series with passed separator
replace() Replace occurrences of pattern/regex with some other string or the return
wrap() Split long strings into lines with length less than a given width
extract() Call re.search on each element, returning DataFrame with one row for eac
extractall() Call re.findall on each element, returning DataFrame with one row for each
E i l tt t t i
strip() Equivalent to str.strip
메소드 설명
rstrip() Equivalent to str.rstrip