ㅅㅇ
Pandas _ 02-4 DataFrame 접근 _ 컬럼/행의 값 조회 및 변경 본문
Pandas_02-4 DataFrame 접근 _ 컬럼/행의 값 조회 및 변경
1. 열 (컬럼) 조회 _ 방법 1 ) 대괄호
(1) df [ '컬럼명' ] # 열 순번 안됨. 슬라이싱도 안됨. - > 하면 인덱스 순번으로 인식한다.
: 한 컬럼(열) 조회.
=> series 로 반환. 결과의 index명 = DF 행 index명
# 1. 한 컬럼(열)을 조회할 경우 series 로 반환.
grade['국어']
- > Series로 반환
# series의 index명(각각의 값의 키로)으로 DF의 index명이 온다.
# Name : 국어 => 국어 컬럼 조회한 결과야.
ID
id-1 100.0
id-2 50.0
id-3 NaN
id-4 90.0
id-5 85.0
Name: 국어, dtype: float64
(2) df.컬럼명
- 컬럼명이 변수 규칙에 맞을 경우만 사용 가능.
# 2.
grade.합계
# grade.점수 합계 # 변수 규칙에 맞지 않는 컬럼이름은 점 표기법으로 조회할 수 없다. 에러.!
grade['점수 합계']
(3) 팬시 indexing
: 한번에 여러 개의 컬럼을 조회할 경우 컬럼명들을 담은 리스트로 조회
=> Fancy indexing : 조회할 컬럼들을 '리스트로 묶어서' 전달
=> DataFrame 로 반환.
# 3. 한번에 여러 컬럼의 값을 조회할 경우 => Fancy indexing
grade[['점수 합계', '평균', 'pass']]
- 주의
- 대괄호 조회는 없는 컬럼의 경우 exception을 발생시킨다.
- df[컬럼 열 순번 ] 는 안된다.
- df[0:3] 슬라이싱도 안한다. 슬라이싱은 행 조회다.
= > 만약 indexing이나 slicing을 이용해 컬럼값 조회하려면 df.columns 속성 을 이용한다.
- `df [ df.columns[ 1 : 3 ] ]`
# 컬럼의 순번으로 조회해야 하는 경우가 있다면?
grade[grade.columns[:4]]
# 이렇게 순번으로 조회하고 싶을 때를 위해 컬럼명을 변수에 미리 담아둔다.
cols = grade.columns
grade[cols[:4]]
2. 열 (컬럼) 조회 _ 방법 2) 다양한 열선택 기능을 제공하는 메소드들
2.1 특정 데이터 타입 의 열들을 조회
select_dtypes(include=[데이터타입,..], exclude=[데이터타입,..])
- 전달한 데이터 타입의 열들을 조회.
- include : 조회할 열 데이터 타입
- exclude : 제외하고 조회할 열 데이터 타입
# float64, int64 타입의 컬럼만 조회
grade.select_dtypes(include = ['float64','int64'])
# float64, int64 타입의 컬럼을 제외하고 조회
grade.select_dtypes(exclude = ['float64', 'int64'])
2.2 매개변수에 전달하는 열의 이름에 따라 조회
filter (items=[], like='', regex='')
- 각 매개변수 중 하나만 사용할 수 있다.
(1) items = [ ]
- 리스트와 일치하는 열들 조회
- 하나의 열 조회에도 DF로 반환한다.
- 이름이 일치하지 않아도 Error 발생 안함. // 대괄호 방법은 없는 열 조회 시 exception 발생
- 다중 열 조회 시 없는 컬럼이 있더라도, 없는 컬럼 제외하고 조회
# 하나의 열 조회 DF 반환
grade.filter(items=['국어'])
# 다중 열 조회 DF 반환
grade.filter(items=['국어','수학','지리'])
(2) like = ' '
- 전달한 문자열이 들어간, 부분일치하는 열들 조회. 부분일치 개념
- 하나만 가능.
- 많이 쓴다.
# 국어과목을 다 조회하고 싶다면?
# 컬럼명에 '국어'가 들어가는 컬럼들을 모두 조회
grade.filter(like = '국어')
(3) regex = ' '
- 정규 표현식을 이용해 열 명의 패턴으로 조회
# \w 어떤 값들이 들어온다라는 뜻
# 2$ : 2 로 끝이난다라는 뜻
# \d : 숫자 한글자
# \d$ : 정수로 끝이 난다라는 뜻
# [123] : 1또는2또는3이 이곳에 자리한다라는 뜻
# 사이에는 + 로 이어준다.
grade.filter(regex=r"\w+2$") #2로 끝나는 컬럼을 조회
grade.filter(regex=r"\w+\d$") # 정수로 끝나는
# actor_1_name, actor_2_name, actor_3_name 컬럼의 값을 조회
movie_df.filter(regex=r'actor_\d_name')
movie_df.filter(regex=r'actor_[123]_name')
지금까지 마치 SQL의 select절처럼 전체 조회 또는 특정 컬럼에 대해 조회를 했다.
그렇다면, 이제 원하는 행을 조회할 것이다.
Series는 1차원 구조로 index명과 값으로만 이뤄져 있다. 그렇기에 대괄호 조회든 록 아이록 조회든 결과는 동일하다.
하지만, 데이터 프레임의 경우,
컬럼 조회와 행 조회에 따라 사용해야 할 방법이 다르다.
3. 행 조회 _ loc, iloc
loc : index 이름으로 조회
iloc : 행 순번으로 조회 (음수 인덱스 양수 인덱스)
- 함수가 아니다. indexer 변수이다. 뒤에 대괄호가 붙는다.
3.1 loc : 행 이름 (index 명)으로 조회
(1) DF.loc[ index이름 ]
- 한 행 조회.
- 조회할 행 index 이름(레이블) 전달
- 이름이 문자열이면 " " 문자열표기법으로 전달. 정수이며 정수표기법으로 전달한다.
# id-3 행을 조회 - 한행 조회 => Series로 반환 (index명 : 컬럼명)
grade.loc['id-3']
(2) DF.loc[ index이름 리스트 ]
- 여러 행 조회.
- 팬시 인덱스
- 조회할 행 index 이름(레이블) 리스트로 묶어 전달
# id-3 , id-5 여러행 조회 => DataFrame로 반환
grade.loc[['id-3','id-5']]
(3) DF.loc[start index이름 : end index이름: step]
- 슬라이싱 지원
- end index 이름의 행까지 포함한다.! (이름으로 슬라이싱할 때는 포함!!)
grade.loc['id-2':'id-4']
grade.loc[::2]
grade.loc['id-5':'id-2':-1]
(4) 특정 value를 조회 - 행과 열을 지정해서 조회
DF.loc[index이름 , 컬럼이름] .loc[행, 열]
** grade.loc[국어, 수학]이 안되는 이유. 펜싱인덱싱 늘 리스트로 묶어야 하는 이유
grade.loc['id-2','영어'] # 행 'id-2' 열 '영어' 인 값
- [행, 열] 틀에서 행과 열을 인덱싱, 슬라이싱, 펜싱해서 작성가능. 조합해서도 가능.
# 행, 열을 loc으로 같이 조회할 경우 행과 열에 슬라이싱 할 수 있다.
grade.loc['id-2':'id-4', '수학':'과학']
# 행에 슬라이싱, 열에 펜싱
grade.loc['id-2':'id-4', ['수학','과학']]
- 컬럼 명 조회 결과가 시리즈라 이렇게도 조회가능하지만, 굳이 안 쓰고 위 방법 사용.
# grade.loc['id-2']['영어']
3.2 iloc : 행 순번 (인덱스 순번) 으로 조회
- 양수인덱스, 음수인덱스
(1) DF.iloc[행번호]
- 한 행 조회.
- 조회할 행 번호 전달
(2) DF.iloc[ 행번호 리스트 ]
- 여러 행 조회.
- 조회할 행 번호 리스트 전달
(3) DF.iloc[start 행번호: stop 행번호: step]
- 슬라이싱 지원
- stop 행번호 포함 안함.
# 0번 행을 조회
grade.iloc[0]
# 음수 index => -1 : 마지막 행
grade.iloc[-1]
# 여러 행 조회 - 펜싱
grade.iloc[[1,3,-1]]
# slicing - iloc indexer의 경우 end index는 포함하지 않는다.
grade.iloc[1:4]
# 역순 reverse 전체 조회
grade.iloc[::-1]
(4) DF.loc[행번호 , 열번호]
- 행과 열 조회
- 행열 모두 순번으로 지정
# 1번째행의 3번 컬럼
grade.iloc[1,3]
# 펜시, 슬라이싱으로 담아서도 가능.
grade.iloc[[0,3],[1,3,5]]
grade.iloc[[0,3],:4]
grade.iloc[1:4,5:9]
4. Boolean indexing을 이용한 조회
- 행, 열에 조건식을 이용해 원하는 조건의 행이나 열을 조회
- 보통, 행 조회 시 사용한다. (sql where 절 처럼)
- 조건 : bool series => 조건을 행(인덱스) 또는 열(컬럼) 조회 자리에 넣어서!
ex) grade['국어'] >= 70
- 다중 조건의 경우 ( )로 묶는다.
- 논리연산자 & | ~
- iloc[]은 boolean indexing을 지원하지 않는다.
DataFrame객체[조건] DataFrame객체.loc[조건]
- 조건이 True인 행만 조회
- 열까지 선택시
- DataFrame객체[조건][열]
- DataFrame객체.loc[조건, 열]
ex1) 국어점수가 70점 이상인 행
조건 : grade['국어'] >= 70 == > bool series
bool series에서 True 인 행을 조회한다.
# True 인 행을 조회
grade[grade['국어']>=70]
ex2) 국어점수가 70점 이상인 행의 '국어', '평균'
grade[grade['국어'>=70]] == > 데이터 프레임
== > 데이터 프레임의 컬럼을 선택해 조회
grade[grade['수학']>=75][['수학','평균']]
ex3) 수학이 100점인 행
grade.loc[grade['수학']==100]
ex4) 수학이 100점인 행의 수학과 평균을 조회
#1 조회결과가 데이터 프레임 => 데이터 프레임의 컬럼을 선택해 조회
grade.loc[grade['수학']==100][['수학','평균']]
#2 loc[행, 열] : loc[boolean indexing, 열선택]
grade.loc[grade['수학']==100, ['수학', '평균']]
- 다중 조건 논리 연산자 사용
# 수학 100점이고 과학은 60점 이상 (둘다 True 행을 조회 => &)
grade.loc[(grade['수학']==100) & (grade['과학']>=60), ['수학','과학']]
# 수학이 100점이거나 paas2 불합격(pass=False)
grade[(grade['수학']==100) | (grade['pass2']=='불합격')][['수학','pass2']]
# 수학이 100점이 아닌 행
grade.loc[~(grade['수학'] == 100),'수학']
5. query() 를 이용한 boolean indexing
- DF.query(조회조건)
- sql의 where 절의 조건처럼 문자열의 query statement를 이용해 조건으로 조회
(문자열로 조건을 만들어서)
- boolean index에 비해
- 장점: 편의성(문자열로 query statement를 만들므로 동적 구문 생성등 다양한 처리가 가능)과 가독성이 좋다.
- 단점: 속도가 느리다.
- 조회조건 구문 (문자열 안에 조건문)
- "컬럼명 연산자 비교값"
- 외부변수를 이용해 query문의 비교값을 지정할 수 있다.
- query 문자열 안에서 @변수명 사용 (변수에 담아둔 값을 불러와 조건의 피연산자가 된다.)
- f string이나 format() 함수를 이용해 query를 만든다.
# 외부 변수에 값을 query 구문에서 사용
name = "신비한"
df.query("name == @name") # 변수에 담긴 데이터 문자열로 인식해 조건 찾는다.
# f.string 방법
name = '박영희'
df.query(f"name == '{name}'")
[ 연산자 ]
(1) 비교 연산자
- ==, >, >=, <, <=, !=
df.query("age == 32")
df.query("tall>=170")
# 문자열이 들어갈 때 쌍 홀 따옴표 쓰기
df.query("name == '김영수'")
(2) 결측치 비교 - Series 의 메소드 사용
- 컬럼.isna(), isnull()
- 컬럼.notna(), notnull()
# 결측치 조회- Series의 메소드 사용
df.query("tall.isnull()", engine='python')
df.query("tall.isna()", engine='python')
df.query("tall.notnull()", engine='python')
df.query("tall.notna()", engine='python')
(3) 논리 연산자
- and(&), or(|), not(~)
- 피연산자 괄호는 ~() 일때만. not 붙이면 괄호 안 씀.
# 논리연산 and &
df.query("age >20 & tall > 180")
df.query("age >20 and tall > 180")
# 논리연산 or |
df.query("age> 30 | tall > 190")
df.query("age> 30 or tall > 190")
# 논리연산 not ~()
df.query("~(tall<190)")
df.query("not tall<190")
(4) in 연산자
- in, ==
- not in, !=
- 비교 대상값은 '리스트'에 넣는다.
df.query("name in ["강강찬", "이순신"]")
df.query("name not in ['강감찬', '이순신']")
# 이렇게도 가능하긴 하다.
df.query("name == ['김영수','강감찬']")
df.query("name != ['김영수','강감찬']")
(5) Index name으로 검색
- 원하는 행을 직접 행 이름으로 검색하는 것.
- 순번이 아니다. 인덱스 명으로 하는 것이다. (현재 예제 데이터프레임의 인덱스명이 순번으로 지정되어 있을 뿐)
df.query("index > 3 ")
df.query("index == [1, 5, 6]")
(6) 문자열 부분검색 (sql의 like)
- 컬럼명.str.contains(문자열) : 문자열을 포함하고 있는
- 컬럼명.str.startswith(문자열) : 문자열로 시작하는
- 컬럼명.str.endswith(문자열) : 문자열로 끝나는
# 1. 특정 문자열을 포함하는
df.query('name.str.contains("영")', engine = 'python')
# 2. 특정 문자열로 시작하는
df.query('name.str.startswith("김")', engine = 'python')
# 3. 특정 문자열로 끝나는
df.query('name.str.endswith("동")', engine = 'python')
- 문자열 부분검색을 할 컬럼에 결측치(NaN)이 있으면 안된다.
- > 방법1 논리연산자 and 로 null인 것 제외
파이썬의 경우 and 연산일 때 앞의 피연산자 조건이 틀리면 뒤 조건을 보지도 않음.
movie_df.query('director_name.notnull() and director_name.str.contains("James")', engine='python')
- > 방법2
현재, 조건이 담긴 문자열에서 NaN 값이 존재할 경우 True 또는 False가 아니라 NaN을 반환한다.
이 결과를 받아 행을 취득하려고 하면 당연히 에러 발생.
이때, na를 True나 False로 치환해준다.
결측치 포함하려면 : na = True, 결측치 포함하지 않으려면 na = False
# 결과 데이터프레임에 결측치 미포함
movie_df.query('director_name.str.contains("James", na = False)', engine='python')
# 결과 데이터프레임에 결측치 포함
movie_df.query('director_name.str.contains("James", na = True)', engine='python')
- Series 메소드 사용하는 (2) (6) 의 경우, error 발생할 수 도 있다.
TypeError: unhashable type: 'Series'
파이썬 넘파이 버전 문제인 것 같기도 하지만, 일단 다시 설치를 하기가 힘들어 방법을 구글링하였다.
구글링 결과 query 함수에 들어가는 쿼리문을 해석하는 엔진 기본값으로 'numexpr' 로 설정되어 있고
이 엔진이 isnull 함수를 해석하지 못하기 때문이라고 한다.
=> 엔진을 바꿔주면 된다. 아래와 같이 engine 인자에 'python' 을 넣어주면 된다.
df.query('B.isnull()', engine='python')
** (참고) 쥬피터 노트북에서는 print 안 하고 바로 반환해야 한다.
[정리 ]
series의 구조는 1차원(one axis) => 행 또는 열. => 인덱스명( 및 순번 )과 값으로 구성되어 있다.
- > 인덱스명, 순번으로 조회가능. 방법 여러가지.
DataFrame의 구조는 2차원(0축, 1축)이다. => 0축 : 행 (인덱스명) 1축: 열 (컬럼명)
- 인덱스 행 조회 : 인덱스명, 순번으로 조회가능
- 록(인덱스명) 조회
- 아이록(순번) 조회
=> 한 행이면 시리즈 반환. series의 index = df 컬럼명
=> 여러 행(펜시). DF 반환
- 대괄호에 인덱스, 슬라이싱하면 행 조회 (컬럼 열 조회 아님!)
- 컬럼 열 조회 : 컬럼명으로만 조회가능. 순번으로 조회불가능. df.colums를 이용해 index변수로 뽑아 조회가능
- 대괄호 조회
=> 한 행이면 시리즈 반환. series의 index = df 인덱스명
=> 여러 행(펜시). DF 반환
- 대괄호 조회 슬라이싱 . 인덱싱 . -> 인덱스 행 조회로 인식
- 메소드 조회
filter() 매개변수 : items, like, regex
- 특정 values 값 조회 : (행, 열)
- loc(이름)조회 (콤마 기준으로)
- iloc(순번) 조회 (콤마 기준으로)
- grade.loc['id-2']['영어'] 이렇게는 잘 안쓴다.
- boolean indexing
- 조건 : bool series
- 조건을 인덱스 값으로 넣어서 (보통 행 조회)
- DataFrame객체[조건] # 컬럼 별이 아니라, 각 행마다 True 인 행을 반환
- DataFrame객체.loc[조건]
2차원 자료구조 DataFrame의 조회결과는
=> 컬럼별, 인덱스별 => series 또는 DataFrame 반환
-> 인덱싱, 슬라이싱, 펜시인덱싱(다중) 조회로 하나씩 뽑을 수 있다.
-> 조회한 값 시리즈나 데이터프레임에 대해 또 메소드나 연산이나 처리 할 수 있다.
ex) movie_df.select_dtypes(exclude=['int64','float64']).info()
- DF의 한 컬럼(열)/ 한 인덱스(열) 을 조회할 경우
=> series 로 반환.
이렇게 조회한 결과들에 대해 메소드 등 처리가 가능하다.
- DF의 여러 컬럼, 여러 인덱스 의 값을 조회할 경우 => Fancy indexing : 조회할 컬럼들을 리스트로 묶어서 전달
=> DataFrame 로 반환.
이렇게 조회한 결과들에 대해 메소드 등 처리가 가능하다.
- 내가 편한 방법 정하기 -
- 컬럼명 조회할 때는 대괄호 또는 filter.
- 인덱스명 조회할 때는 loc 쓰자.
'AI_STUDY > Pandas' 카테고리의 다른 글
Pandas _ 03-2 집계 (0) | 2022.06.09 |
---|---|
Pandas _ 03-1 정렬 (0) | 2022.06.09 |
Pandas _ 02-3 DataFrame 접근 _ 컬럼/행 조회 및 변경 (0) | 2022.06.08 |
Pandas _ 02-2 DataFrame 주요 메소드, 속성 (0) | 2022.06.08 |
Pandas _ 02-1 DataFrame 개요 & 생성 및 저장 (0) | 2022.06.07 |