티스토리 뷰

머신러닝

Pandas 너 뭐니?_첫번째

느린 개미 2018. 6. 10. 16:38
반응형

아래 Pandas 관련 내용은 인프런 : 밑바닥부터 시작하는 머신러닝 입문 과정의 최성철 교수님 강의의 pandas 부분을 수강하고, 나름대로 한번 정리를 하여 더 오래 기억하고자 작성한 사항입니다.

일부 추가, 삭제, 수정한 사항들도 있습니다.

1. Pandas 는?

  • 구조화된 데이터의 처리를 지원하는 Python 라이브러리
  • 고성능 Array 계산 라이브러리인 Numpy 와 통합하여, 강력한 "스프레드시트" 처리 기능을 제공
  • Python계의 엑셀!!

2. 데이터 로딩

In [146]:
import pandas as pd
In [147]:
data_url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data' #Data URL
df_data = pd.read_csv(data_url, sep='\s+', header = None) #csv 타입 데이터 로드, separate는 빈공간으로 지정하고, Column은 없음
In [148]:
df_data.head() #처음 다섯줄 출력
Out[148]:
012345678910111213
00.0063218.02.3100.5386.57565.24.09001296.015.3396.904.9824.0
10.027310.07.0700.4696.42178.94.96712242.017.8396.909.1421.6
20.027290.07.0700.4697.18561.14.96712242.017.8392.834.0334.7
30.032370.02.1800.4586.99845.86.06223222.018.7394.632.9433.4
40.069050.02.1800.4587.14754.26.06223222.018.7396.905.3336.2

3. Series

  • DataFrame 중 하나의 Column 에 해당하는 데이터의 모음 Object
In [149]:
from pandas import Series, DataFrame
import numpy as np
In [150]:
example_obj = Series()
In [151]:
list_data = [1, 2, 3, 4, 5]
example_obj = Series(data = list_data)
example_obj
Out[151]:
0    1
1    2
2    3
3    4
4    5
dtype: int64
  • index : index 이름을 지정
  • dtype : data type 설정
  • name : series 이름 설정
In [152]:
list_data = [1, 2, 3, 4, 5]
list_name = ["a", "b", "c", "d", "e"]
example_obj = Series(data = list_data, index = list_name, dtype = np.float32, name = "example_data") #index 이름을 지정
example_obj
Out[152]:
a    1.0
b    2.0
c    3.0
d    4.0
e    5.0
Name: example_data, dtype: float32
  • 바로 dict type 할당도 가능
In [153]:
dict_data = {"a":1, "b":2, "c":3, "d":4, "e":5}
example_obj = Series(dict_data, dtype = np.float32, name = "example_data") #index 이름을 지정
example_obj
Out[153]:
a    1.0
b    2.0
c    3.0
d    4.0
e    5.0
Name: example_data, dtype: float32
  • data index 에 접근하기 & data index에 값 할당하기
In [154]:
example_obj["a"]
Out[154]:
1.0
In [155]:
example_obj["a"] = 3.2
example_obj
Out[155]:
a    3.2
b    2.0
c    3.0
d    4.0
e    5.0
Name: example_data, dtype: float32
  • 깂 리스트만 & index 리스트만
In [156]:
example_obj.values
Out[156]:
array([ 3.20000005,  2.        ,  3.        ,  4.        ,  5.        ], dtype=float32)
In [157]:
example_obj.index
Out[157]:
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
  • index 값을 기준으로 Series 생성
In [158]:
dict_data_1 = {"a":1, "b":2, "c":3, "d":4, "e":5}
indexes = ["a", "b", "c", "d", "e", "f", "g", "h"]
series_obj_1 = Series(dict_data_1, index=indexes)
series_obj_1
Out[158]:
a    1.0
b    2.0
c    3.0
d    4.0
e    5.0
f    NaN
g    NaN
h    NaN
dtype: float64

4. Dataframe Overview

  • 각 column 들은 다른 데이터 타입을 가질 수 있다.
  • row 와 column index 가 있다.
  • Series 를 모아서 만든 Data Table = 기본 2차원 이다.
In [159]:
# Example from - https://chrisalbon.com/python/pandas_map_values_to_values.html
raw_data = {'first_name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'],
        'last_name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze'],
        'age': [42, 52, 36, 24, 73],
        'city': ['San Francisco', 'Baltimore', 'Miami', 'Douglas', 'Boston']}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'city'])
df
Out[159]:
first_namelast_nameagecity
0JasonMiller42San Francisco
1MollyJacobson52Baltimore
2TinaAli36Miami
3JakeMilner24Douglas
4AmyCooze73Boston
  • column 선택
In [160]:
DataFrame(raw_data, columns = ["age", "city"])
Out[160]:
agecity
042San Francisco
152Baltimore
236Miami
324Douglas
473Boston
  • 새로운 column 추가
In [161]:
df =DataFrame(raw_data, 
          columns = ["first_name","last_name","age", "city", "debt"]
         )
In [162]:
df.debt
Out[162]:
0    NaN
1    NaN
2    NaN
3    NaN
4    NaN
Name: debt, dtype: object
In [163]:
df["debt"]
Out[163]:
0    NaN
1    NaN
2    NaN
3    NaN
4    NaN
Name: debt, dtype: object
  • ioc : index location
  • iloc : index position
In [164]:
df.head()
Out[164]:
first_namelast_nameagecitydebt
0JasonMiller42San FranciscoNaN
1MollyJacobson52BaltimoreNaN
2TinaAli36MiamiNaN
3JakeMilner24DouglasNaN
4AmyCooze73BostonNaN
In [165]:
df.loc[1]
Out[165]:
first_name        Molly
last_name      Jacobson
age                  52
city          Baltimore
debt                NaN
Name: 1, dtype: object
In [166]:
df["age"].iloc[1:]
Out[166]:
1    52
2    36
3    24
4    73
Name: age, dtype: int64
  • Column에 새로운 데이터 할당
In [167]:
df.debt = df.age > 40
df
Out[167]:
first_namelast_nameagecitydebt
0JasonMiller42San FranciscoTrue
1MollyJacobson52BaltimoreTrue
2TinaAli36MiamiFalse
3JakeMilner24DouglasFalse
4AmyCooze73BostonTrue
  • Transpose
In [168]:
df.T
Out[168]:
01234
first_nameJasonMollyTinaJakeAmy
last_nameMillerJacobsonAliMilnerCooze
age4252362473
citySan FranciscoBaltimoreMiamiDouglasBoston
debtTrueTrueFalseFalseTrue
  • 값 출력
In [169]:
df.values
Out[169]:
array([['Jason', 'Miller', 42, 'San Francisco', True],
       ['Molly', 'Jacobson', 52, 'Baltimore', True],
       ['Tina', 'Ali', 36, 'Miami', False],
       ['Jake', 'Milner', 24, 'Douglas', False],
       ['Amy', 'Cooze', 73, 'Boston', True]], dtype=object)
  • column 을 삭제함
In [170]:
del df["debt"]
df
Out[170]:
first_namelast_nameagecity
0JasonMiller42San Francisco
1MollyJacobson52Baltimore
2TinaAli36Miami
3JakeMilner24Douglas
4AmyCooze73Boston

5. Selection & Drop

  • 한개의 column 선택 시
In [171]:
df["first_name"].head(3)
Out[171]:
0    Jason
1    Molly
2     Tina
Name: first_name, dtype: object
  • 1개 이상의 column 선택
In [172]:
df [["first_name", "last_name", "age"]].head(3)
Out[172]:
first_namelast_nameage
0JasonMiller42
1MollyJacobson52
2TinaAli36
  • index 재설정
In [173]:
import numpy as np
df = pd.read_excel("excel-comp-data.xlsx")
df.head()
Out[173]:
accountnamestreetcitystatepostal-codeJanFebMar
0211829Kerluke, Koepp and Hilpert34456 Sean HighwayNew JaycobTexas28752100006200035000
1320563Walter-Trantow1311 Alvis TunnelPort KhadijahNorthCarolina38365950004500035000
2648336Bashirian, Kunde and Price62184 Schamberger Underpass Apt. 231New LilianlandIowa765179100012000035000
3109996D'Amore, Gleichner and Bode155 Fadel Crescent Apt. 144HyattburghMaine460214500012000010000
4121213Bauch-Goldner7274 Marissa CommonShanahanchesterCalifornia4968116200012000035000
In [174]:
df.index = list(range(10,25))
df.head()
Out[174]:
accountnamestreetcitystatepostal-codeJanFebMar
10211829Kerluke, Koepp and Hilpert34456 Sean HighwayNew JaycobTexas28752100006200035000
11320563Walter-Trantow1311 Alvis TunnelPort KhadijahNorthCarolina38365950004500035000
12648336Bashirian, Kunde and Price62184 Schamberger Underpass Apt. 231New LilianlandIowa765179100012000035000
13109996D'Amore, Gleichner and Bode155 Fadel Crescent Apt. 144HyattburghMaine460214500012000010000
14121213Bauch-Goldner7274 Marissa CommonShanahanchesterCalifornia4968116200012000035000
  • Data drop

index number 로 drop

In [175]:
df.drop(10).head()
Out[175]:
accountnamestreetcitystatepostal-codeJanFebMar
11320563Walter-Trantow1311 Alvis TunnelPort KhadijahNorthCarolina38365950004500035000
12648336Bashirian, Kunde and Price62184 Schamberger Underpass Apt. 231New LilianlandIowa765179100012000035000
13109996D'Amore, Gleichner and Bode155 Fadel Crescent Apt. 144HyattburghMaine460214500012000010000
14121213Bauch-Goldner7274 Marissa CommonShanahanchesterCalifornia4968116200012000035000
15132971Williamson, Schumm and Hettinger89403 Casimer SpringJeremieburghArkansas6278515000012000035000

한개 이상의 index number로 drop

In [176]:
df.drop([10,11,12,13,14]).head()
Out[176]:
accountnamestreetcitystatepostal-codeJanFebMar
15132971Williamson, Schumm and Hettinger89403 Casimer SpringJeremieburghArkansas6278515000012000035000
16145068Casper LLC340 Consuela Bridge Apt. 400Lake GabriellatonMississipi180086200012000070000
17205217Kovacek-Johnston91971 Cronin Vista Suite 601DeronvilleRhodeIsland534611450009500035000
18209744Champlin-Morar26739 Grant LockLake JulianntonPennsylvania64415700009500035000
19212303Gerhold-Maggio366 Maggio Grove Apt. 998North RasIdaho463087000012000035000

axis 지정으로 축을 기준으로 drop => column 중에 "city"

In [177]:
df.drop("city", axis=1).head()
Out[177]:
accountnamestreetstatepostal-codeJanFebMar
10211829Kerluke, Koepp and Hilpert34456 Sean HighwayTexas28752100006200035000
11320563Walter-Trantow1311 Alvis TunnelNorthCarolina38365950004500035000
12648336Bashirian, Kunde and Price62184 Schamberger Underpass Apt. 231Iowa765179100012000035000
13109996D'Amore, Gleichner and Bode155 Fadel Crescent Apt. 144Maine460214500012000010000
14121213Bauch-Goldner7274 Marissa CommonCalifornia4968116200012000035000

6. Dataframe Operations

Series operation

index 를 기준으로 연산수행. 겹치는 index 가 없을 경우 NaN값으로 반환

In [178]:
s1 = Series(
    range(1,6), index=list("abced"))
s1
Out[178]:
a    1
b    2
c    3
e    4
d    5
dtype: int32
In [179]:
s2 = Series(
    range(5,11), index=list("bcedef"))
s2
Out[179]:
b     5
c     6
e     7
d     8
e     9
f    10
dtype: int32
In [180]:
s1 + s2
Out[180]:
a     NaN
b     7.0
c     9.0
d    13.0
e    11.0
e    13.0
f     NaN
dtype: float64

Dataframe operation

In [181]:
df1 = DataFrame(
    np.arange(9).reshape(3,3), 
    columns=list("abc"))
df1
Out[181]:
abc
0012
1345
2678
In [182]:
df2 = DataFrame(
    np.arange(16).reshape(4,4), 
    columns=list("abcd"))
df2
Out[182]:
abcd
00123
14567
2891011
312131415
In [183]:
df1 + df2
Out[183]:
abcd
00.02.04.0NaN
17.09.011.0NaN
214.016.018.0NaN
3NaNNaNNaNNaN
In [184]:
df1.add(df2,fill_value=0)
Out[184]:
abcd
00.02.04.03.0
17.09.011.07.0
214.016.018.011.0
312.013.014.015.0

7. Lambda, Map 함수

Lambda

  • 한 줄로 함수를 표현하는 익명 함수 기법
  • lambda argument : expression

map 함수

  • map(function, sequence)
  • sequence 데이터에 모두 function 적용

두 개 이상의 argument 가 있을 때는 두 개의 sequence 형을 써야함

In [185]:
ex = [1,2,3,4,5]
f = lambda x,y : x+y
list(map(f, ex, ex))
Out[185]:
[2, 4, 6, 8, 10]

익명 함수 그대로 사용할 수 있음

In [186]:
list(map(lambda x: x+x, ex))
Out[186]:
[2, 4, 6, 8, 10]

map for Series

  • Pandas 의 series type 의 데이터에도 map 함수 사용 가능
In [187]:
s1 = Series(np.arange(10))
s1.head()
Out[187]:
0    0
1    1
2    2
3    3
4    4
dtype: int32
In [188]:
s1.map(lambda x: x**2).head(5)
Out[188]:
0     0
1     1
2     4
3     9
4    16
dtype: int64

Dict type으로 데이터 교체. 없는 값은 NaN

In [216]:
z = {1: 'A', 2: 'B', 3: 'C'}
s1.map(z).head(5)
Out[216]:
0    NaN
1      A
2      B
3      C
4    NaN
dtype: object

같은 위치의 데이터를 s2 로 전환

In [190]:
s2 = Series(np.arange(10, 20))
s1.map(s2).head(5)
Out[190]:
0    10
1    11
2    12
3    13
4    14
dtype: int32

아래와 같이 unique 함수를 이용해 명목형 변수를 숫자로 변환하는 방법으로도 많이 사용함

In [191]:
df = pd.read_csv("wages.csv")
df.head()
Out[191]:
earnheightsexraceedage
079571.29901173.89malewhite1649
196396.98864366.23femalewhite1662
248710.66694763.77femalewhite1633
380478.09615363.22femaleother1695
482089.34549863.08femalewhite1743
In [192]:
df.sex.unique()
Out[192]:
array(['male', 'female'], dtype=object)
In [193]:
df["sex_code"] = df.sex.map({"male":0, "female":1})
df.head(5)
Out[193]:
earnheightsexraceedagesex_code
079571.29901173.89malewhite16490
196396.98864366.23femalewhite16621
248710.66694763.77femalewhite16331
380478.09615363.22femaleother16951
482089.34549863.08femalewhite17431

Replace function

  • Map 함수의 기능 중 데이터 변환 기능만 담당
  • 데이터 변환 시 많이 사용하는 함수
In [217]:
df.sex.replace(
    {"male":0, "female":1}
).head()
Out[217]:
0    0
1    1
2    1
3    1
4    1
Name: sex, dtype: int64
In [218]:
df.sex.replace(
          ["male", "female"], [0, 1], inplace = True)
df.head(5)
Out[218]:
earnheightsexraceedage
079571.29901173.89001649
196396.98864366.23101662
248710.66694763.77101633
380478.09615363.22111695
482089.34549863.08101743

apply for dataframe

  • map 과 달리, series 전체(column)에 해당 함수를 적용
  • 입력값이 series 데이터로 입력받아 handling 가능
  • 각 column 별로 결과값 반환
In [196]:
df_info = df[["earn", "height", "age"]]
df_info.head()
Out[196]:
earnheightage
079571.29901173.8949
196396.98864366.2362
248710.66694763.7733
380478.09615363.2295
482089.34549863.0843
In [197]:
f = lambda x : x.max()-x.min()
df_info.apply(f)
Out[197]:
earn      318047.708444
height        19.870000
age           73.000000
dtype: float64
  • 내장 연산 함수를 사용할 때도 똑같은 효과를 거둘 수 있음 (mean, std 등 사용 가능)
In [198]:
df_info.sum()
Out[198]:
earn      4.474344e+07
height    9.183125e+04
age       6.250800e+04
dtype: float64
In [199]:
df_info.apply(sum)
Out[199]:
earn      4.474344e+07
height    9.183125e+04
age       6.250800e+04
dtype: float64

applymap for dataframe

  • series 단위가 아닌 element 단위로 함수를 적용함
  • series 단위에 apply 를 적용시킬 때와 같은 효과
In [200]:
f = lambda x: -x
df_info.applymap(f).head()
Out[200]:
earnheightage
0-79571.299011-73.89-49
1-96396.988643-66.23-62
2-48710.666947-63.77-33
3-80478.096153-63.22-95
4-82089.345498-63.08-43

8. Pandas Built-in functions

describe

  • Numeric type 데이터의 요약 정보를 보여줌
In [201]:
df = pd.read_csv("wages.csv")
df.head()
Out[201]:
earnheightsexraceedage
079571.29901173.89malewhite1649
196396.98864366.23femalewhite1662
248710.66694763.77femalewhite1633
380478.09615363.22femaleother1695
482089.34549863.08femalewhite1743
In [202]:
df.describe()
Out[202]:
earnheightedage
count1379.0000001379.0000001379.0000001379.000000
mean32446.29262266.59264013.35460545.328499
std31257.0700063.8181082.43874115.789715
min-98.58048957.3400003.00000022.000000
25%10538.79072163.72000012.00000033.000000
50%26877.87017866.05000013.00000042.000000
75%44506.21533669.31500015.00000055.000000
max317949.12795577.21000018.00000095.000000

Unique

  • series data의 유일한 값을 list 로 반환함
In [203]:
df.race.unique()
Out[203]:
array(['white', 'other', 'hispanic', 'black'], dtype=object)
  • index를 추출할 때도 사용
In [204]:
np.array(dict(enumerate(df.race.unique())))
Out[204]:
array({0: 'white', 1: 'other', 2: 'hispanic', 3: 'black'}, dtype=object)
In [205]:
value = list(map(int,np.array(list(enumerate(df.race.unique())))[:, 0]))
value
Out[205]:
[0, 1, 2, 3]
In [206]:
key = np.array(list(enumerate(df.race.unique())))[: , 1].tolist()
key
Out[206]:
['white', 'other', 'hispanic', 'black']
  • index labelling (race 열을 0-3 까지의 숫자값으로 변환)
In [207]:
df["race"].replace(to_replace=key, value = value, inplace=True)
In [208]:
df.head()
Out[208]:
earnheightsexraceedage
079571.29901173.89male01649
196396.98864366.23female01662
248710.66694763.77female01633
380478.09615363.22female11695
482089.34549863.08female01743

isnull

  • column 또는 row 값의 NaN (null) 값의 index 를 반환함
In [209]:
df.isnull().head()
Out[209]:
earnheightsexraceedage
0FalseFalseFalseFalseFalseFalse
1FalseFalseFalseFalseFalseFalse
2FalseFalseFalseFalseFalseFalse
3FalseFalseFalseFalseFalseFalse
4FalseFalseFalseFalseFalseFalse
In [210]:
df.isnull().sum()  #Null 인 값의 합
Out[210]:
earn      0
height    0
sex       0
race      0
ed        0
age       0
dtype: int64

sort_values

  • column 값을 기준으로 데이터를 sorting
  • ascending : 오름차순
In [211]:
df.sort_values(["age", "earn"], ascending=True ).head(10)
Out[211]:
earnheightsexraceedage
1038-56.32197967.81male21022
800-27.87681972.29male01222
963-25.65526068.90male01222
1105988.56507064.71female01222
8011000.22150464.09female01222
8621002.02384366.59female01222
9331007.99494168.26female01222
9881578.54281464.53male01222
5221955.16818769.87female31222
7652581.87040264.79female01222

Correlation(상관계수) & Covariance(공분산)

In [212]:
df.age.corr(df.earn)
Out[212]:
0.074003491778360547
In [213]:
df.age.cov(df.earn)
Out[213]:
36523.6992104089
In [214]:
df_info.corrwith(df.earn)
Out[214]:
earn      1.000000
height    0.291600
age       0.074003
dtype: float64
  • 추가적으로 공분산과 상관계수의 차이를 찾아보았다. 
    공분산은 단위변수에 영향을 받는다. 따라서 상관계수는 그것을 보완하기 위하여, 
    절대적 크기에 영향을 받지 않도록 단위화 시켰다고 생각하면 된다.즉, 분산의 크기만큼 나누었다고 생각하면 된다.
    따라서 상관계수는 -1 <= 상관계수 <= 1 의 성질을 가진다.

출처) http://destrudo.tistory.com/15

  • corr 와 corrwith 의 차이도 무엇인지 찾아보니, 이미 stackoverflow 에 친절히 누가 물어봐주셨다 
    고마워요!! 

corrwith (두개 dataframe 간에)
computes correlation with another dataframe:
between rows or columns of two DataFrame objects

corr (한 dataframe 에서 column 간에)
computes it with itself
Compute pairwise correlation of columns

출처) https://stackoverflow.com/questions/46041148/pandas-corr-vs-corrwith

Pandas_1.ipynb


In [ ]:
 


반응형

'머신러닝' 카테고리의 다른 글

[데이터전처리_1] Feature Scaling  (0) 2018.10.16
Pandas 너 뭐니?_두번째  (0) 2018.06.26
numpy 를 이해해보자  (2) 2018.06.01
머신러닝 분류  (0) 2018.05.16
의사결정나무(decisiontree)_2  (0) 2018.05.14