티스토리 뷰

머신러닝

Pandas 너 뭐니?_두번째

느린 개미 2018. 6. 26. 22:24
반응형

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

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

1. Groupby

In [4]:
# data from: 
import pandas as pd 

ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}

df = pd.DataFrame(ipl_data)
df
Out[4]:
PointsRankTeamYear
08761Riders2014
17892Riders2015
28632Devils2014
36733Devils2015
47413Kings2014
58124kings2015
67561Kings2016
77881Kings2017
86942Riders2016
97014Royals2014
108041Royals2015
116902Riders2017
In [6]:
df.groupby("Team")["Points"].sum()
Out[6]:
Team
Devils    1536
Kings     2285
Riders    3049
Royals    1505
kings      812
Name: Points, dtype: int64
  • ("Team") : 묶음의 기준이 되는 칼럼
  • ["Points"] : 적용받는 컬럼
  • sum() : 적용받는 연산
In [37]:
df.groupby("Team", as_index=False )["Points"].sum() 
#as_index 옵션을 통해 아래와 같이 할 수도 있음
Out[37]:
TeamPoints
0Devils1536
1Kings2285
2Riders3049
3Royals1505
4kings812

한 개이상의 column을 묶을 수 있음

In [9]:
h_index = df.groupby(["Team", "Year"])["Points"].sum()
h_index
Out[9]:
Team    Year
Devils  2014    863
        2015    673
Kings   2014    741
        2016    756
        2017    788
Riders  2014    876
        2015    789
        2016    694
        2017    690
Royals  2014    701
        2015    804
kings   2015    812
Name: Points, dtype: int64

unstack()

Group으로 묶여진 데이터를 matrix 형태로 전환해줌

In [10]:
h_index.unstack()
Out[10]:
Year2014201520162017
Team
Devils863.0673.0NaNNaN
Kings741.0NaN756.0788.0
Riders876.0789.0694.0690.0
Royals701.0804.0NaNNaN
kingsNaN812.0NaNNaN

Hierarchical index – swaplevel

index 레벨을 변경할 수 있음

In [13]:
h_index.swaplevel()
Out[13]:
Year  Team  
2014  Devils    863
2015  Devils    673
2014  Kings     741
2016  Kings     756
2017  Kings     788
2014  Riders    876
2015  Riders    789
2016  Riders    694
2017  Riders    690
2014  Royals    701
2015  Royals    804
      kings     812
Name: Points, dtype: int64
In [15]:
h_index.swaplevel().sort_index(level=0)
Out[15]:
Year  Team  
2014  Devils    863
      Kings     741
      Riders    876
      Royals    701
2015  Devils    673
      Riders    789
      Royals    804
      kings     812
2016  Kings     756
      Riders    694
2017  Kings     788
      Riders    690
Name: Points, dtype: int64
In [ ]:
Index 레벨을 기준으로 기본 연산 수행 가능
In [16]:
h_index.sum(level=0)
Out[16]:
Team
Devils    1536
Kings     2285
Riders    3049
Royals    1505
kings      812
Name: Points, dtype: int64
In [17]:
h_index.sum(level=1)
Out[17]:
Year
2014    3181
2015    3078
2016    1450
2017    1478
Name: Points, dtype: int64

2. Groupby 에 의해 split 된 정보 추출

In [18]:
grouped = df.groupby("Team")
In [19]:
for name, group in grouped:
    print(name)
    print(group)
Devils
   Points  Rank    Team  Year
2     863     2  Devils  2014
3     673     3  Devils  2015
Kings
   Points  Rank   Team  Year
4     741     3  Kings  2014
6     756     1  Kings  2016
7     788     1  Kings  2017
Riders
    Points  Rank    Team  Year
0      876     1  Riders  2014
1      789     2  Riders  2015
8      694     2  Riders  2016
11     690     2  Riders  2017
Royals
    Points  Rank    Team  Year
9      701     4  Royals  2014
10     804     1  Royals  2015
kings
   Points  Rank   Team  Year
5     812     4  kings  2015

특정 key 값을 가진 group 만 추출 가능

In [22]:
grouped.get_group("Devils")
Out[22]:
PointsRankTeamYear
28632Devils2014
36733Devils2015

3. Group 정보에 세가지 유형의 apply 가 가능

  • Aggregation : 요약된 통계정보를 추출해 줌
  • Transformation: 해당 정보를 변환해줌
  • Filtration: 특정 정보를 제거 하여 보여주는 필터링 기능

Aggretation

In [24]:
grouped.agg(sum)
Out[24]:
PointsRankYear
Team
Devils153654029
Kings228556047
Riders304978062
Royals150554029
kings81242015
In [28]:
import numpy as np

grouped.agg(np.mean)
Out[28]:
PointsRankYear
Team
Devils768.0000002.5000002014.500000
Kings761.6666671.6666672015.666667
Riders762.2500001.7500002015.500000
Royals752.5000002.5000002014.500000
kings812.0000004.0000002015.000000

특정 컬럼에 여러개의 function을 Apply 할 수도 있음

In [30]:
grouped["Points"].agg([np.sum, np.mean, np.std])
Out[30]:
summeanstd
Team
Devils1536768.000000134.350288
Kings2285761.66666724.006943
Riders3049762.25000088.567771
Royals1505752.50000072.831998
kings812812.000000NaN
In [41]:
df.groupby(["Team"]).agg({"Points":sum, "Rank":min, "Year":"count"})
Out[41]:
PointsRankYear
Team
Devils153622
Kings228513
Riders304914
Royals150512
kings81241
In [42]:
df.groupby(["Team"]).agg({"Points": [min, max, sum], 
                          "Rank":"count", 
                          "Year":["first", "unique"]})
Out[42]:
PointsRankYear
minmaxsumcountfirstunique
Team
Devils673863153622014[2014, 2015]
Kings741788228532014[2014, 2016, 2017]
Riders690876304942014[2014, 2015, 2016, 2017]
Royals701804150522014[2014, 2015]
kings81281281212015[2015]

transformation

  • Aggregation과 달리 key값 별로 요약된 정보가 아님
  • 개별 데이터의 변환을 지원함
  • max 나 min 처럼 Series 데이터에 적용되는 데이터들은 key 값을 기준으로 Grouped 된 데이터 기준
In [34]:
grouped.transform(np.mean) # 위의 agg 와 결과 차이를 살펴보자
Out[34]:
PointsRankYear
0762.2500001.7500002015.500000
1762.2500001.7500002015.500000
2768.0000002.5000002014.500000
3768.0000002.5000002014.500000
4761.6666671.6666672015.666667
5812.0000004.0000002015.000000
6761.6666671.6666672015.666667
7761.6666671.6666672015.666667
8762.2500001.7500002015.500000
9752.5000002.5000002014.500000
10752.5000002.5000002014.500000
11762.2500001.7500002015.500000

filter

  • 특정 조건으로 데이터를 검색할 때 사용
  • filter 안에는 boolen 조건이 존재해야함
  • len(x)는 grouped된 dataframe 개수
In [36]:
df.groupby("Team").filter(lambda x: len(x)>=3 )
Out[36]:
PointsRankTeamYear
08761Riders2014
17892Riders2015
47413Kings2014
67561Kings2016
77881Kings2017
86942Riders2016
116902Riders2017

4. Pivot Table

  • 우리가 Excel 에서 보던 그 것
  • Index 축은 groupby와 동일
  • Column에 추가로 labelling 값을 추가
  • Value에 numeric type 값을 aggregation 하는 형태
In [48]:
import dateutil

df_phone = pd.read_csv("phone_data.csv")
df_phone['date'] = df_phone['date'].apply(dateutil.parser.parse, dayfirst=True)
df_phone.head()
Out[48]:
indexdatedurationitemmonthnetworknetwork_type
002014-10-15 06:58:0034.429data2014-11datadata
112014-10-15 06:58:0013.000call2014-11Vodafonemobile
222014-10-15 14:46:0023.000call2014-11Meteormobile
332014-10-15 14:48:004.000call2014-11Tescomobile
442014-10-15 17:27:004.000call2014-11Tescomobile
In [49]:
df_phone.pivot_table(["duration"],
                     index = [df_phone.month, df_phone.item],
                    columns = df_phone.network, aggfunc="sum", fill_value=0)
Out[49]:
duration
networkMeteorTescoThreeVodafonedatalandlinespecialvoicemailworld
monthitem
2014-11call152140451245843160.000290603010
data0000998.4410000
sms10325550.0000100
2014-12call20101819631613020.000142406900
data00001032.8700000
sms12113180.0000004
2015-01call22072904644536260.000160302850
data00001067.2990000
sms10333400.0000000
2015-02call11884087627918640.00073002680
data00001067.2990000
sms1211230.0000200
2015-03call274973496635130.0001177002310
data0000998.4410000
sms045130.0000003

5. Crosstab

  • 두 칼럼에 교차 빈도, 비율, 덧셈 등을 구할 때 사용
  • Pivot Table 의 특수한 형태
  • User-Item Rating Matrix 등을 만들 때 사용 가능함
In [51]:
df_movie = pd.read_csv("movie_rating.csv")
df_movie.head()
Out[51]:
critictitlerating
0Jack MatthewsLady in the Water3.0
1Jack MatthewsSnakes on a Plane4.0
2Jack MatthewsYou Me and Dupree3.5
3Jack MatthewsSuperman Returns5.0
4Jack MatthewsThe Night Listener3.0
In [55]:
pd.crosstab(index = df_movie.critic,
           columns = df_movie.title,
           values = df_movie.rating, aggfunc="first").fillna(0)
Out[55]:
titleJust My LuckLady in the WaterSnakes on a PlaneSuperman ReturnsThe Night ListenerYou Me and Dupree
critic
Claudia Puig3.00.03.54.04.52.5
Gene Seymour1.53.03.55.03.03.5
Jack Matthews0.03.04.05.03.03.5
Lisa Rose3.02.53.53.53.02.5
Mick LaSalle2.03.04.03.03.02.0
Toby0.00.04.54.00.01.0
In [57]:
df_movie.pivot_table(["rating"],
                    index = df_movie.critic,
                    columns = df_movie.title, 
                    aggfunc = "sum", fill_value = 0)
Out[57]:
rating
titleJust My LuckLady in the WaterSnakes on a PlaneSuperman ReturnsThe Night ListenerYou Me and Dupree
critic
Claudia Puig3.00.03.54.04.52.5
Gene Seymour1.53.03.55.03.03.5
Jack Matthews0.03.04.05.03.03.5
Lisa Rose3.02.53.53.53.02.5
Mick LaSalle2.03.04.03.03.02.0
Toby0.00.04.54.00.01.0

6. Merge

  • SQL 에서 많이 사용하는 Merge 와 같은 기능
  • 두 개의 데이터를 하나로 합침

subject_id 기준으로 merge

In [ ]:
pd.merge(df_a, df_b, on='subject_id')

두 dataframe이 column이름이 다를 때

In [ ]:
pd.merge(df_a, df_b, left_on='subject_id', right_on='subject_id2')
  • left join
In [ ]:
pd.merge(df_a, df_b, on='subject_id', how='left')
  • right join
In [ ]:
pd.merge(df_a, df_b, on='subject_id', how='right')
  • outer join
In [ ]:
pd.merge(df_a, df_b, on='subject_id', how='outer')
  • inner join
In [ ]:
pd.merge(df_a, df_b, on='subject_id', how='inner')
  • index based join
In [ ]:
pd.merge(df_a, df_b, right_index = True, left_index = True)

7. Concat

같은 형태의 데이터를 붙이는 연산작업

  • row 아래로 붙임
In [ ]:
df_new = pd.concat([df_a, df_b])
df_nex.reset_index()

또는

In [ ]:
df_a.append(df_b)
  • column 옆으로 붙임
In [ ]:
df_new = pd.concat([df_a, df_b], axis=1)
df_nex.reset_index()

8. DB Persistence

  • DB loading 시 db connection 기능을 제공함
In [62]:
import sqlite3

conn = sqlite3.connect("./data/flights.db")
cur = conn.cursor()
cur.execute("select * from airlines limit 5;")
results = cur.fetchall()
  • db 연결 conn 을 사용하여 dataframe 생성
In [68]:
df_airlines = pd.read_sql_query("select * from airlines;", conn)

9. XLS Persistence

  • DataFrame 의 엑셀 추출 코드
  • Xls 엔진으로 openpyxls 또는 XlsxWrite 사용
In [71]:
writer = pd.ExcelWriter("./data/df_airlines.xlsx", engine = 'xlsxwriter')
df_airlines.to_excel(writer, sheet_name='Sheet1')

10. Pickle Persistence

  • 가장 일반적인 python 파일 persistence
  • to_pickle, read_pickle 함수 사용
In [72]:
df_airlines.to_pickle("./data/df_airlines.pickle")
In [73]:
df_airlines_pickle = pd.read_pickle("./data/df_airlines.pickle")
df_airlines_pickle.head()
Out[73]:
indexidnamealiasiataicaocallsigncountryactive
001Private flight\N-NoneNoneNoneY
112135 Airways\NNoneGNLGENERALUnited StatesN
2231Time Airline\N1TRNXNEXTIMESouth AfricaY
3342 Sqn No 1 Elementary Flying Training School\NNoneWYTNoneUnited KingdomN
445213 Flight Unit\NNoneTFUNoneRussiaN


반응형

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

[데이터전처리_2] missing value 처리  (0) 2018.10.17
[데이터전처리_1] Feature Scaling  (0) 2018.10.16
Pandas 너 뭐니?_첫번째  (0) 2018.06.10
numpy 를 이해해보자  (2) 2018.06.01
머신러닝 분류  (0) 2018.05.16