import numpy as np
import pandas as pd
03wk-2: Pandas – 행과 열의 선택
1. 강의영상
2. Imports
3. Pandas: 행과 열의 선택
-
두 가지 형태의 데이터프레임
= {'date': ['12/30','12/31','01/01','01/02','01/03'], 'X1': [65,95,65,55,80], 'X2': [55,100,90,80,30], 'X3': [50,50,60,75,30], 'X4': [40,80,30,80,100]}
dct = pd.DataFrame(dct)
df df
date | X1 | X2 | X3 | X4 | |
---|---|---|---|---|---|
0 | 12/30 | 65 | 55 | 50 | 40 |
1 | 12/31 | 95 | 100 | 50 | 80 |
2 | 01/01 | 65 | 90 | 60 | 30 |
3 | 01/02 | 55 | 80 | 75 | 80 |
4 | 01/03 | 80 | 30 | 30 | 100 |
= pd.DataFrame({'X1': [65,95,65,55,80], 'X2': [55,100,90,80,30], 'X3': [50,50,60,75,30], 'X4': [40,80,30,80,100]}, index=['12/30','12/31','01/01','01/02','01/03'])
ts ts
X1 | X2 | X3 | X4 | |
---|---|---|---|---|
12/30 | 65 | 55 | 50 | 40 |
12/31 | 95 | 100 | 50 | 80 |
01/01 | 65 | 90 | 60 | 30 |
01/02 | 55 | 80 | 75 | 80 |
01/03 | 80 | 30 | 30 | 100 |
A. 열의 선택
-
방법1: df.?
+ str
# df.X1
-
방법2: df[?]
+ str, [str,str]
# df['X1'] # str
# df[['X1']] # [str]
# df[['X1','X3']] # [str,str]
-
방법3: df.iloc[:,?]
+ int, int:int, [int,int], [bool,bool], range
# df.iloc[:,0] # int
# df.iloc[:,-2:] # int:int - 슬라이싱
# df.iloc[:,1::2] # int:int - 스트라이딩
# df.iloc[:,[0]] # [int]
# df.iloc[:,[0,1]] # [int,int]
# df.iloc[:,[True,True,False,False]] # bool의 list
# df.iloc[:,range(2)] # range
-
방법4: df.loc[:,?]
+ str, ‘str:str’, [str,str], [bool,bool]
# df.loc[:,'X1'] # str
# df.loc[:,'X1':'X3'] # 'str':'str' -- 칼럼이름으로 슬라이싱 **
# df.loc[:,'X1'::2] # 'str':'str' -- 칼럼이름으로 스트라이딩 **
# df.loc[:,['X1']] # [str]
# df.loc[:,['X1','X4']] # [str,str]
# df.loc[:,[True,False,False,True]] # bool의 list
B. 행의 선택
-
방법1: df[]
+ int:int, str:str, [bool,bool], pd.Series([bool,bool]) – \((\star\star\star\star\star)\)
# df[:2] # int:int -- 슬라이싱 // df.iloc[:2,:], df.iloc[:2] 와 같음
# df[::2] # int:int -- 스트라이딩
# ts['12/30':'01/02'] # str:str -- 슬라이싱
# ts['12/31'::2] # str:str -- 스트라이딩
# df[['12' in date for date in df.date]] # [bool,bool]
# df[df.X1 < 70] # pd.Series([bool,bool])
-
방법2: df.iloc[]
, df.iloc[,:]
+ int, int:int, [int,int], [bool,bool], range
# df.iloc[0] # int
# df.iloc[-2:] # int:int -- 슬라이싱
# df.iloc[1::2] # int:int -- 스트라이딩
# df.iloc[[0]] # [int]
# df.iloc[[0,1]] # [int,int]
# df.iloc[['12' in date for date in df.date]] # [bool,bool]
# df.iloc[range(2)] # range
# df.iloc[0,:] # int
# df.iloc[-2:,:] # int:int -- 슬라이싱
# df.iloc[1::2,:] # int:int -- 스트라이딩
# df.iloc[[0],:] # [int]
# df.iloc[[0,1],:] # [int,int]
# df.iloc[['12' in date for date in df.date],:] # [bool,bool]
# df.iloc[range(2),:] # range
-
방법3: df.loc[]
, df.loc[,:]
+ int, str, int:int, str:str, [int,int], [str,str], [bool,bool], pd.Series([bool,bool])
# df.loc[0] # int
# ts.loc['12/30'] # str
# df.loc[:2] # int:int
# ts.loc[:'01/02'] # str:str
# df.loc[[0,1]] # [int,int]
# ts.loc[['12/30','01/01']] # [str,str]
# df.loc[['12' in date for date in df.date]] # [bool,bool]
# df.loc[df.X1>70] # pd.Series([bool,bool])
D. 제 스타일
-
가장 안전한 코드
# df.loc[:,:]
-
상황1: 하나의 col을 뽑으려 할때 좋은 코드
# df.X1 # 최애
# df['X1'] # 차애
# df[['X1']] # 차애
-
상황2: row 슬라이싱을 할때 좋은 코드 \((\star\star\star)\)
# df[:5] # 최애
# ts[:'01/02'] # 시계열인 경우
-
상황3: 조건에 맞는 row를 뽑을때 좋은 코드
# df[df.X1<60] # 최애
# df.loc[['12' in date for date in df.date]] # 차애
-
상황4: 하나의 row를 뽑으려 할때 좋은 코드
# df.iloc[0] # 최애
# df.loc[0] # 차애
-
상황5: (row,col)을 뽑으려 할때 좋은 코드
# 최애: pd.Series를 뽑고 -> 인덱스로접근
# df.X1[0]
# df['X1'][0]
# 차애: iloc, loc 으로 한번에 뽑기
# df.iloc[0,0]
# df.loc[0,'X1']
위의 상황이외에는 df.loc[:,:]
를 사용하는것이 유리하다
-
상황6: column 슬라이싱을 할때
# df.loc[:,'X1':'X3'] # 끝점포함
-
상황7: row + column 슬라이싱을 하는 가장 좋은 코드
2,'X1':'X2'] df.loc[::
X1 | X2 | |
---|---|---|
0 | 65 | 55 |
2 | 65 | 90 |
4 | 80 | 30 |
-
상황8: 조건에 맞는 col을 뽑기에 가장 좋은 코드
# df.loc[:,[len(colname)>2 for colname in df.columns]]
-
상황9: 조건에 맞는 row, col을 뽑기에 가장 좋은 코드
# df.loc[df.X1>70,[len(colname)>2 for colname in df.columns]]
D. 제 스타일 X
-
제가 안쓰는 코드1
1] df[:
date | X1 | X2 | X3 | X4 | |
---|---|---|---|---|---|
0 | 12/30 | 65 | 55 | 50 | 40 |
이러면 내 입장에서는 마치 아래가 동작할 것 같잖아..
0] df[
KeyError: 0
-
제가 안쓰는 코드2: bool의 list를 사용할때 iloc은 가급적 쓰지마세요
list(df['X1']<80),:] df.iloc[
date | X1 | X2 | X3 | X4 | |
---|---|---|---|---|---|
0 | 12/30 | 65 | 55 | 50 | 40 |
2 | 01/01 | 65 | 90 | 60 | 30 |
3 | 01/02 | 55 | 80 | 75 | 80 |
이러면 마치 아래도 동작할 것 같잖아..
'X1']<80,:] df.iloc[df[
NotImplementedError: iLocation based boolean indexing on an integer type is not available
E. 요약
-
알아두면 좋은 규칙
.iloc[]
와.iloc[,:]
는 완전히 동등하다..loc[]
와.loc[,:]
는 완전히 동등하다.- 결과를
pd.Series
형태가 아닌pd.DataFrame
형태로 얻고 싶다면[[?]]
를 사용하면 된다.
-
정리
type of indexer | . |
[] |
.iloc |
.loc |
내가 쓴다면? |
---|---|---|---|---|---|
int | X | X | O | \(\Delta\) | df.iloc[3,:] |
int:int | X | O | O | \(\Delta\) | df[3:5] |
[int,int] | X | X | O | \(\Delta\) | df.iloc[idx,:] |
str | X | X | X | O | ts.loc['time1',:] |
str:str | X | O | X | O | ts.loc['time1':'time2',:] |
[str,str] | X | X | X | O | 안할 듯 |
[bool,bool] | X | O | O | O | df[filtered_idx] |
pd.Series([bool,bool]) | X | O | X | O | df[df.X1>20] |
type of indexer | . |
[] |
.iloc |
.loc |
내가 쓴다면? |
---|---|---|---|---|---|
int | X | X | O | X | df.iloc[:,0] |
int:int | X | X | O | X | df.iloc[:,0:2] |
[int,int] | X | X | O | X | df.iloc[:,idx] |
str | O | O | X | O | df.loc[:,'X1'] |
str:str | X | X | X | O | df.loc[:,'X1':'X4'] |
[str,str] | X | O | X | O | df.loc[:,colname_list] |
[bool,bool] | X | X | O | O | df.loc[:,bool_list] |
4. HW
아래와 같은 데이터프레임이 있다고 하자.
=pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Pandas-Cookbook/master/data/movie.csv')
df df
color | director_name | num_critic_for_reviews | duration | director_facebook_likes | actor_3_facebook_likes | actor_2_name | actor_1_facebook_likes | gross | genres | ... | num_user_for_reviews | language | country | content_rating | budget | title_year | actor_2_facebook_likes | imdb_score | aspect_ratio | movie_facebook_likes | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Color | James Cameron | 723.0 | 178.0 | 0.0 | 855.0 | Joel David Moore | 1000.0 | 760505847.0 | Action|Adventure|Fantasy|Sci-Fi | ... | 3054.0 | English | USA | PG-13 | 237000000.0 | 2009.0 | 936.0 | 7.9 | 1.78 | 33000 |
1 | Color | Gore Verbinski | 302.0 | 169.0 | 563.0 | 1000.0 | Orlando Bloom | 40000.0 | 309404152.0 | Action|Adventure|Fantasy | ... | 1238.0 | English | USA | PG-13 | 300000000.0 | 2007.0 | 5000.0 | 7.1 | 2.35 | 0 |
2 | Color | Sam Mendes | 602.0 | 148.0 | 0.0 | 161.0 | Rory Kinnear | 11000.0 | 200074175.0 | Action|Adventure|Thriller | ... | 994.0 | English | UK | PG-13 | 245000000.0 | 2015.0 | 393.0 | 6.8 | 2.35 | 85000 |
3 | Color | Christopher Nolan | 813.0 | 164.0 | 22000.0 | 23000.0 | Christian Bale | 27000.0 | 448130642.0 | Action|Thriller | ... | 2701.0 | English | USA | PG-13 | 250000000.0 | 2012.0 | 23000.0 | 8.5 | 2.35 | 164000 |
4 | NaN | Doug Walker | NaN | NaN | 131.0 | NaN | Rob Walker | 131.0 | NaN | Documentary | ... | NaN | NaN | NaN | NaN | NaN | NaN | 12.0 | 7.1 | NaN | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4911 | Color | Scott Smith | 1.0 | 87.0 | 2.0 | 318.0 | Daphne Zuniga | 637.0 | NaN | Comedy|Drama | ... | 6.0 | English | Canada | NaN | NaN | 2013.0 | 470.0 | 7.7 | NaN | 84 |
4912 | Color | NaN | 43.0 | 43.0 | NaN | 319.0 | Valorie Curry | 841.0 | NaN | Crime|Drama|Mystery|Thriller | ... | 359.0 | English | USA | TV-14 | NaN | NaN | 593.0 | 7.5 | 16.00 | 32000 |
4913 | Color | Benjamin Roberds | 13.0 | 76.0 | 0.0 | 0.0 | Maxwell Moody | 0.0 | NaN | Drama|Horror|Thriller | ... | 3.0 | English | USA | NaN | 1400.0 | 2013.0 | 0.0 | 6.3 | NaN | 16 |
4914 | Color | Daniel Hsia | 14.0 | 100.0 | 0.0 | 489.0 | Daniel Henney | 946.0 | 10443.0 | Comedy|Drama|Romance | ... | 9.0 | English | USA | PG-13 | NaN | 2012.0 | 719.0 | 6.3 | 2.35 | 660 |
4915 | Color | Jon Gunn | 43.0 | 90.0 | 16.0 | 16.0 | Brian Herzlinger | 86.0 | 85222.0 | Documentary | ... | 84.0 | English | USA | PG | 1100.0 | 2004.0 | 23.0 | 6.6 | 1.85 | 456 |
4916 rows × 28 columns
이 데이터프레임의 columns은 아래와 같다.
df.columns
Index(['color', 'director_name', 'num_critic_for_reviews', 'duration',
'director_facebook_likes', 'actor_3_facebook_likes', 'actor_2_name',
'actor_1_facebook_likes', 'gross', 'genres', 'actor_1_name',
'movie_title', 'num_voted_users', 'cast_total_facebook_likes',
'actor_3_name', 'facenumber_in_poster', 'plot_keywords',
'movie_imdb_link', 'num_user_for_reviews', 'language', 'country',
'content_rating', 'budget', 'title_year', 'actor_2_facebook_likes',
'imdb_score', 'aspect_ratio', 'movie_facebook_likes'],
dtype='object')
actor
라는 단어가 포함된 column만을 선택하는 코드를 작성하라.
# 출력결과는 아래와 같다.
actor_3_facebook_likes | actor_2_name | actor_1_facebook_likes | actor_1_name | actor_3_name | actor_2_facebook_likes | |
---|---|---|---|---|---|---|
0 | 855.0 | Joel David Moore | 1000.0 | CCH Pounder | Wes Studi | 936.0 |
1 | 1000.0 | Orlando Bloom | 40000.0 | Johnny Depp | Jack Davenport | 5000.0 |
2 | 161.0 | Rory Kinnear | 11000.0 | Christoph Waltz | Stephanie Sigman | 393.0 |
3 | 23000.0 | Christian Bale | 27000.0 | Tom Hardy | Joseph Gordon-Levitt | 23000.0 |
4 | NaN | Rob Walker | 131.0 | Doug Walker | NaN | 12.0 |
... | ... | ... | ... | ... | ... | ... |
4911 | 318.0 | Daphne Zuniga | 637.0 | Eric Mabius | Crystal Lowe | 470.0 |
4912 | 319.0 | Valorie Curry | 841.0 | Natalie Zea | Sam Underwood | 593.0 |
4913 | 0.0 | Maxwell Moody | 0.0 | Eva Boehnke | David Chandler | 0.0 |
4914 | 489.0 | Daniel Henney | 946.0 | Alan Ruck | Eliza Coupe | 719.0 |
4915 | 16.0 | Brian Herzlinger | 86.0 | John August | Jon Gunn | 23.0 |
4916 rows × 6 columns
hint: 아래는 column 이름이 5글자 이하인 열을 출력하는 코드를 작성한 것이다.
len(col_name)<=5 for col_name in df.columns]] df.loc[:,[
color | gross | |
---|---|---|
0 | Color | 760505847.0 |
1 | Color | 309404152.0 |
2 | Color | 200074175.0 |
3 | Color | 448130642.0 |
4 | NaN | NaN |
... | ... | ... |
4911 | Color | NaN |
4912 | Color | NaN |
4913 | Color | NaN |
4914 | Color | 10443.0 |
4915 | Color | 85222.0 |
4916 rows × 2 columns
note: [len(col_name)<=5 for col_name in df.columns]
와 같은 컴프리헨션 문법이 익숙하지 않다면
의 리스트컴프리헨션을 복습할 것