Python_Pandas_02-3(DataFrame)
5.2. 열 추가
- 새로운 열을 지정 후 값을 대입하면 새로운 열을 추가할 수 있다.
보통 파생변수를 만들 때 사용한다.
- 열 추가
df['col_name'] = value
마지막 열로 추가된다.
하나의 값을 대입하면 모든 행에 그 값이 대입된다.
다른 값을 주려면 배열에 담아서 대입한다.
- 열 삽입
df.insert(삽입할 위치 index, 삽입할 열이름, 값)
- 파생변수생성
기존 열들의 값을 이용해서 만든 열을 파생변수라고 한다.
벡터화 연산을 이용하여 값 대입한다.
df['col_name'] = 기존 열들을 이용한 연산
변수 grade에 grade2.csv 파일 읽어오기
import pandas as pd
grade = pd.read_csv("saved_data/grade2.csv")
grade.set_index("id", inplace=True)
grade
컬럼을 추가
# 컬럼을 추가
grade["수학"] = 100 # 수학 컬럼을 생성, 모든행에 100을 대입. 없는 컬럼에 값 대입 -> 추가
grade
있는 컬럼에 값을 대입 -> 수정
grade["수학"] = 80 # 수학컬럼의 값을 변경. 있는 컬럼에 값을 대입 -> 수정
grade
리스트 형태로 값 삽입
grade["수학"] = [70, 100, 90, 40, 70] # 값의 개수 = 행수. 1차원 자료구조(리스트, 시리즈), 시리즈로 사용시 index name이 일치해야함
grade
Series 사용하여 값 삽입
grade['과학'] = pd.Series([70, 100, 90, 40, 70], index = grade.index) # Series 사용
grade
series + series -> 같은 행의 값끼리 계산한다.
# series + series -> 같은 행의 값끼리 계산한다.
sum_result = grade['국어'] + grade['영어'] + grade['수학'] + grade['과학']
sum_result
파생변수 생성
# 파생변수 생성
grade['총점'] = sum_result
grade
파생변수 생성
# 파생변수 생성
grade['평균'] = grade['총점'] / 4
grade
grade.to_csv('saved_data/grade_result.csv') # csv파일로 작업 저장
# 변수 r에 저장된 csv파일 읽어오기
r = pd.read_csv('saved_data/grade_result.csv', index_col=0)
r
변수 grade에 다시 grade2.csv 파일 읽어오기
grade = pd.read_csv('saved_data/grade2.csv', index_col='id')
grade
axis
# axis = 1 -> 행끼리의 합, axis = 0 -> 열끼리의 합
total = grade.sum(axis=1)
mean = grade.mean(axis=1)
grade['총점'] = total
grade['평균'] = mean
grade
TODO
- 패스 여부를 boolean값으로 저장하는 파생변수 열을 추가
열이름: 합격여부
평균점수가 80미만이면 False,이상이면 True가 나오도록 처리
grade['합격여부'] = grade['평균'] >= 80
grade
numpy를 이용한 파생변수 열 추가
import numpy as np
grade['합격여부2'] = np.where(grade['평균'] >= 80, '합격', '불합격') # True : 합격, False : 불합격 으로 변경
grade
행, 열의 값 조회
- indexer 연산자를 이용한다.
행은 loc indexer, iloc indexer를 사용한다.
- 열은 indexing만 되고 slicing은 안된다.
- 행은 indexing, slicing 모두 지원한다.
6.1. 열의 값 조회
- df['열이름']
열이름의 열 조회
- df.열이름
열이름이 Python 식별자 규칙에 맞으면 . 표기법을 사용할 수 있다.
- Fancy indexing
여러개의 열들을 한번에 조회할 경우 열이름들을 리스트로 묶어서 전달한다.
- 주의
열은 순번으로는 조회할 수 없다.
열 조회 indexer에서 슬라이싱을 하면 행 조회 Slicing이다.
만약 indexing이나 slicing을 이용해 열들을 조회하려면 columns 속성을 이용한다. -> df[df.columns[:3]]
grade['국어'] # 한개 열 조회 -> Series 로 반환.
grade.국어
두 개 이상의 열 조회
grade[['평균', '총점']] # 여러 열을 조회 -> DataFrame으로 반환
grade['국어':'평균'] # 행 조회로 바뀐다.
grade[0:3]
column 속성 이용하여 indexing, slicing
grade[grade.columns[0:4]] # columns 속성을 이용하여 indexing과 slicing을 한다.
TODO
- 다음 movie dataframe을 이용해 코드를 작성
변수 df에 movie_df.csv 파일 읽어오기
import pandas as pd
df = pd.read_csv('saved_data/movie_df.csv')
df.head()
# 1. director_name 컬럼의 값들 조회
df['director_name']
# 2. actor_1_name, actor_2_name, actor_3_name 컬럼의 값들
df[['actor_1_name', 'actor_2_name', 'actor_3_name']]
# 3. 1, 3, 4, 7 번 컬럼 조회('director_name', 'duration', 'director_facebook_likes', 'actor_1_facebook_likes')
# df[['director_name', 'duration', 'director_facebook_likes', 'actor_1_facebook_likes']]
df.drop(columns = 'Unnamed: 0', inplace=True) # 0번 컬럼의 Unnamed: 0 삭제
df[df.columns[[1, 3, 4, 7]]]
# 4. 1 ~ 5 번 컬럼 조회('director_name', 'num_critic_for_reviews', 'duration', director_facebook_likes', 'actor_3_facebook_likes')
df[df.columns[1:6]]
6.1.1. 다양한 열선택 기능을 제공하는 메소드들
- select_dtypes(include=[데이터타입,..], exclude=[데이터타입,..])
전달한 데이터 타입의 열들을 조회.
include : 조회할 열 데이터 타입
exclude : 제외하고 조회할 열 데이터 타입
- filter (items=[], like='', regex='')
매개변수에 전달하는 열의 이름에 따라 조회
각 매개변수중 하나만 사용할 수 있다.
items = [컬럼명들, ..]
- 리스트와 일치하는 열들 조회
- 이름이 일치 하지 않아도 Error 발생안함.
like = '부분일치문자열'
- 전달한 문자열이 들어간 열들 조회
- 부분일치 개념
regex = '정규표현식'
- 정규 표현식을 이용해 열명의 패턴으로 조회
grade.info()
include, exclude
# 데이터 타입으로 조회
# include : 조회하고 싶은 타입들을 지정.
# grade.select_dtypes(include='int64')
grade.select_dtypes(include=['int64', 'bool']) # 특정 데이터 타입의 열을 조회
## exclude: 조회 안할 타입들을 지정.
grade.select_dtypes(exclude=["object", "bool"])
grade_result 생성
grade_result = pd.read_csv("saved_data/grade_result.csv",
index_col=0)
grade_result
컬럼을 중간에 삽입
# 컬럼을 중간에 삽입
grade_result.insert(loc=1, column='국어2', value = 90)
grade_result.insert(loc=4, # 컬럼을 삽입할 위치 -> 순번으로 지정
column='수학2', # 컬럼이름
value=[100,80,55,85,57])
grade_result
filter
grade_result.filter(items=['국어', '국어2', '국어3']) # filter 국어3은 없는 컬럼이여서 조회되지 않는다.
grade_result.filter(like='국어') # 컬럼명에 '국어' 가 들어가는 컬럼들을 조회
정규표현식 이용
# ^ : 시작 .{2} : 두글자 $ : 끝
grade_result.filter(regex=r"^.{2}$") # 정규표현식과 일치하는 컬럼들을 조회
grade_result.filter(regex=r".+어$") # 어 로 끝나는 컬럼 조회
컬럼의 순서를 원하는 순서로 변경
# 컬럼의 순서를 변경 -> 원하는 순서로 조회(fancy indexing 활용)
g = grade_result[['국어','국어2', '수학', '수학2', '영어', '과학', '평균', '총점']]
g
TODO
movie dataframe을 이용해 아래 코드를 작성하시오.
# 1. 정수형(int64) 컬럼만 조회
df.select_dtypes(include = 'int64')
# 2. 정수형(int64)과 실수형(float64) 타입을 제외한 컬럼들만 조회
df.select_dtypes(exclude=['int64', 'float64'])
# 3. actor_1_name, actor_2_name, actor_3_name 컬럼의 값을 조회
# df.filter(['actor_1_name', 'actor_2_name', 'actor_3_name'])
df.filter(regex=r"actor_\d_name") # 정규 표현식 이용
# 4. actor_1_facebook_likes, actor_1_name 컬럼의 값을 조회
# df.filter(['actor_1_facebook_likes', 'actor_1_name'])
df.filter(like = 'actor_1_')
# 5. color, director 컬럼을 조회. 없는 컬럼명이라도 에러가 안나도록 조회하시오.
df.filter(items = ['color', 'director'])
# 6. movie가 들어가는 컬럼들을 조회.
df.filter(like = 'movie')
6.2. 행 조회
- loc : index 이름으로 조회
- iloc : 행 순번으로 조회
6.2.1. loc indexer
- index name으로 조회
- DF.loc[ index이름 ]
한 행 조회.
조회할 행 index 이름(레이블) 전달
이름이 문자열이면 " " 문자열표기법으로 전달. 정수이며 정수표기법으로 전달한다.
- DF.loc[ index이름 리스트 ]
여러 행 조회.
팬시 인덱스
조회할 행 index 이름(레이블) 리스트 전달
- DF.loc[start index이름 : end index이름: step]
슬라이싱 지원
end index 이름의 행까지 포함한다.
- DF.loc[index이름 , 컬럼이름]
행과 열 조회
둘다 이름으로 지정해야 함.
grade.loc['id-3'] # series로 반환 index 이름 : 컬럼명
grade.loc[['id-2', 'id-4']]
grade.loc['id-2' : 'id-4'] # slicing, end index 포함시킨다.
grade['id-5':'id-2':-1] # reverse
행, 열 같이 조회
# 행, 열을 같이 조회
# loc[행이름, 열이름] : 행/열 - indexname, fancy indexing, slicing
grade.loc['id-2', '총점']
grade.loc[['id-2', 'id-3'], '총점']
grade.loc[['id-2', 'id-5'], ['총점', '평균']]
grade.loc['id-1':'id-4', ['국어', '평균']]
grade.loc['id-2':'id-4', '영어':'합격여부']
# loc index : 행/열 모두 이름으로 조회. (순번은 사용못함.)
# grade.loc[1:3]
# grade.loc['id-3', 1]
# indexer 안에서 행, 열을 같이 조회하는 것은 loc,iloc indexer만 가능
grade['국어']['id-2']
grade[['국어','영어']].loc['id-2']
6.2.2. iloc
- index(행 순번)으로 조회
- DF.iloc[행번호]
한 행 조회.
조회할 행 번호 전달
- DF.iloc[ 행번호 리스트 ]
여러 행 조회.
조회할 행 번호 리스트 전달
- DF.iloc[start 행번호: stop 행번호: step]
슬라이싱 지원
stop 행번호 포함 안함.
- DF.iloc[행번호 , 열번호]
행과 열 조회
행열 모두 순번으로 지정
grade.iloc[0]
grade.iloc[2]
grade.iloc[[0, 2, 3]]
grade.iloc[1:3]
grade.iloc[1:-1] # 음수 index 가능
grade.iloc[1, 2] # iloc -> 행/열 모두 순번(index)으로 조회
grade.iloc[[2, 4], 2]
grade.iloc[:4, [0, 1]]
grade.iloc[1:3, 1:]
TODO
- movie dataframe을 이용해 loc과 iloc관련해 다음을 작성
# 1. movie_title 컬럼을 index명으로 지정
import pandas as pd
df = pd.read_csv('saved_data/movie_df.csv')
df1 = df.set_index('movie_title')
df1
# 2. 행이름이 Avatar인 행 조회
df1.loc['Avatar']
# 3. 행이름이 Spider-Man 3, The Avengers, Titanic 인 행 조회
df1.loc[['Spider-Man 3', 'The Avengers', 'Titanic']]
# 4. 행이름 Spectre ~ Robin Hood 까지 범위로 조회
df1.loc['Spectre':'Robin Hood']
# 5. 행이름이 John Carter 이고 열이름이 director_name 인 값 조회 - John Carter의 감독이름
df1.loc[['John Carter'], ['director_name']]
# 6. 1번행 조회
df1.iloc[1]
# 7. 마지막 행 조회
df1.iloc[-1]
# 8. 1, 2, 5, 6, 9 번행 조회
df1.iloc[[1, 2, 5, 6, 9]]
# 9. 10 ~ 20 행 조회
df1.iloc[10:21]
# 10. movie dataframe에서 5 ~ 10 행의 color, director_name, num_critic_for_reviews 컬럼(0,1,2번째 컬럼)을 iloc을 이용해 조회
df1.drop(columns = ['Unnamed: 0'], inplace=True)
df1.iloc[5:11, 0:3]
6.3. Boolean indexing을 이용한 조회
- 원하는 조건을 만족하는 행, 열을 조회한다.
- DataFrame객체[조건], DataFrame객체.loc[조건]
조건이 True인 행만 조회
열까지 선택시
DataFrame객체[조건][열]
DataFrame객체.loc[조건, 열]
- iloc indexer는 boolean indexing을 지원하지 않는다.
- 논리연산자
논리연산자 설명
& and연산
| or연산
~ not 연산
논리연산자의 피연산자들은 반드시 ( )로 묶어준다.
파이썬과는 다르게 and, or, not 예약어는 사용할 수 없다.
df[df['color'] == 'Color'] # 조건이 True인 행이 조회 -> sql select의 where절
df.loc[df['color']=='Black and White']
df.loc[df['color'] == 'Black and White', ['movie_title', 'director_name']]
국어 80점 이상
grade[grade['국어'] >= 80]
grade.loc[grade['국어'] >= 80] # iloc은 boolean indexing을 지원하지 않는다.
국어 70점 이상인 행의 국어 평균 총점 출력
grade.loc[grade['국어'] >= 70, ['국어','평균','총점']]
grade[grade['국어']>=70][['국어','평균','총점']] # 같은 의미이다.
and, or
# 국어, 영어 모두 80점 이상(and)
grade.loc[(grade['국어'] >= 80) & (grade['영어'] >= 80)]
# 국어, 영어 둘 중에 하나 80점 이상(or)
grade.loc[(grade.국어 >= 80) | (grade.영어 >= 80)]
grade.loc[~((grade.국어 >= 80) | (grade.영어 >= 80))]
TODO
- movie dataframe
# 1. 상영시간 (duration)이 300 이상인 영화들 조회
df.loc[df['duration'] >= 300]
# 2. 상영시간 (duration)이 300 이상인 영화들의 영화제목(movie_title)과 감독이름(director_name) 조회
df.loc[df['duration'] >= 300, ['movie_title', 'director_name']]
# 3. 감독이름(director_name)이 'Quentin Tarantino' 의 영화들만 조회
df.loc[df['director_name'] == 'Quentin Tarantino']
# 4. James Cameron의 영화중 상영시간이 150분 이상인 영화들의 제목(movie_title), 상영시간(duration), 컬러여부(color) 조회
df.loc[(df['director_name'] == 'James Cameron') & (df['duration'] >= 150), ['movie_title', 'duration', 'color']]
query() 를 이용한 boolean indexing
- query(조회조건)
sql의 where 절의 조건 처럼 문자열의 query statement를 이용해 조건으로 조회
boolean index에 비해
- 장점: 편의성(문자열로 query statement를 만들므로 동적 구문 생성등 다양한 처리가 가능)과 가독성이 좋다.
- 단점: 속도가 느리다.
- 조회조건 구문
"컬럼명 연산자 비교값"
- 외부변수를 이용해 query문의 비교값을 지정할 수 있다.
query 문자열 안에서 @변수명 사용
f string이나 format() 함수를 이용해 query를 만들 수도 있다.
6.4.1. query 함수 연산자
- 비교 연산자
==, >, >=, <, <=, !=
- 결측치 비교
컬럼.isna(), isnull()
컬럼.notna(), notnull()
- 논리 연산자
and, or, not
- in 연산자
in, ==
not in, !=
비교 대상값은 리스트에 넣는다.
- Index name으로 검색
행의 index 이름으로 검색
- 문자열 부분검색(sql의 like)
컬럼명.str.contains(문자열): 문자열을 포함하고 있는
컬럼명.str.startswith(문자열): 문자열로 시작하는
컬럼명.str.endswith(문자열): 문자열로 끝나는
문자열 부분검색을 할 컬럼에 결측치(NaN)이 있으면 안된다.
DataFrame 생성
import pandas as pd
import numpy as np
data_dict = {
'name':['김영수', '박영희', '오준호', '조민경', '박영희', '김영수'],
'age':[23, 17, 28, 31, 23, 17],
'email':['kys@gmail.com', 'pyh@gmail.com', 'ojh@daum.net', 'cmk@naver.com', 'pyh@daum.net', np.nan]
}
df = pd.DataFrame(data_dict)
df
실습
# 비교연산
df.query("name == '김영수'")
df.query("age > 25")
df.query("name != '김영수'")
# 결측치 비교
df.query("email.isnull()") # 결측치인 것 조회 (or isna())
df.query("email.notnull()") # 결측치가 아닌 것 조회(or notna())
# 논리연산
df.query("not age < 25") # not -> 논리부정
df.query("~(age < 25)") # ~ -> 논리연산자(부정)
df.query("name == '박영희' and age > 20")
df.query("name == '박영희' & age > 20") # ()로 안묶어도 됨.
df.query('name == "박영희" or age > 25')
df.query('name == "박영희" | age > 25')
# in, not in 연산자, ==, !=
df.query('age in [17, 23]')
df.query('age == [17, 23]')
df.query('age not in [17, 23]')
df.query('age != [17, 23]')
# index 이름의 조건으로 비교 -> 컬럼명자리에 "index"
df.query("index > 3")
df.set_index("name").query("index == '김영수'")
df.set_index("name").query("index > '박영희'")
# 문자열 부분조회 (sql의 like 기능)
# ~로 시작하는지?
df.query("name.str.startswith('김')") # 김 으로 시작한다
# ~로 끝나는지?
df.query("name.str.endswith('희')")
# ~를 포함하는지?
df.query("name.str.contains('민경')")
# 부분일치 함수 사용하는 컬럼에는 결측치가 있으면 안된다.
# df.query("email.str.endswith('.com')") -> 오류발생
# 결측치가 있을 경우 -> 결측치 아닌 것들을 조회하고 부분일치 조회.
df.query('email.notnull()').query("email.str.endswith('.com')")
# 조건 비교해서 사용할 값으로 외부의 변수값을 이용하기
first_name = '김'
# df.query(f')
df.query('name.str.startswith(@first_name)')
name = input("이름:")
age = int(input("나이:"))
# 변수의 값의 타입에 맞춰서 query문을 처리
df.query("name == @name and age == @age")
TODO
movie dataframe을 이용해 query() 메소드를 사용
# 1. 상영시간이 300분 이상인 영화들만 조회
df.query("duration >= 300")
# 2. 상영시간이 250분 ~ 300분 인 영화들 조회
df.query("duration >= 250 and duration <= 300")
# 3. 컬러영화가 아닌 영화 조회
df.query("not color == 'Color'")
# 4. 이름에 James가 들어가는 감독의 영화조회
df.query("director_name.notnull()").query("director_name.str.contains('James')")