본문 바로가기
Python/데이터 분석

[DataFrame] DataFrame - 조회하기

by snow_white 2022. 4. 8.

Dataframe은 numpy에서 했던 슬라이싱 방법이 적용되지 않는다!

 

loc는 locate의 줄임말이다. 인덱싱이랑 비슷한데 다른 기능이 있기에 loc라 부른다.

tips[ 행 기준 슬라이싱, 열 기준 슬라이싱 ] -> 에러 발생

 

1. boolean 인덱싱으로 값 가져오기

condition1 = (tips['tip']>=2 )
condition2 = (tips['sex']=='Male')
condition3 = (tips['size']==2)

tips[condition1 & condition2 & condition3].head(3)['time']
tips[condition1 & condition2 & condition3]['time'].head(3)
'''
3    Dinner
6    Dinner
9    Dinner
Name: time, dtype: object
'''

 

2. loc 함수 사용하기

- indexing과 slicing 할 수 있음

- slicing은 [시작(포함) : 끝 (포함)] 규칙에 유의

 

  1. df.loc[ 행조건, 열조건 ], 이때 행 조건 앞, 뒤 전부 다 포함 / 열 조건 앞, 뒤 전부 다 포함

import numpy as np
import pandas as pd 
from pandas import Series, DataFrame
import matplotlib.pyplot as plt

tips =pd.read_csv('../dataset/tips.csv')

# 0~5까지 행일 것 같지만 6까지 나옴!
# 6까지 포함, smoker까지 포함
tips.loc[ :6, : 'smoker']

# 6 (6에 해당하는 행)에서  tip 열만 가져오기
tips.loc[6, 'tip'] # 2.0
tips.loc[condition1 & condition2 & condition3 , 'time'].head(3)
'''
3    Dinner
6    Dinner
9    Dinner
Name: time, dtype: object
'''

 

  • 바로 인덱싱 vs. loc함수 사용
tips[condition1]['tip'].head(3)
tips.loc[condition1,'tip'].head(3)
'''
2    3.50
3    3.31
4    3.61
Name: tip, dtype: float64
'''

값을 바로 할당하지 말고 loc() 함수를 사용해 달라는 권장 경고 나옴!

에러는 아니지만 값이 할당되는 경우도 있지만, 해당 사항은 재대입 되지 않아서 원하는 대로 결과 나오지 않음

tips[condition1]['tip'] = 2
>>A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
tips.loc[condition1,'tip'].head(3)
'''
2    3.50
3    3.31
4    3.61
Name: tip, dtype: float64
'''

boolean indexing으로 값 대입하면 잘 안 나온다. 이게 사실 위험한 작업이다. 조건부 필터링을 걸어서 특정한 칼럼을 새로운 다른 값으로 채우는 일을 많이 한다. 이때 우리는 새로운 값이 잘 대입되었다고 생각하지만 실상을 그렇지 않은 결과가 많다. 분석에 치명적인 실수를 야기하는 부분이다.

 

# loc 를 사용해서 해당 조건(2불 이상)일 때 2로 할당
tips.loc[condition1, 'tip'] = 2

tips.head(10)

 

  • 남성, 흡연자 손님을 필터링
  • tip을 많이 낸 순서대로 정렬
  • 상위 10개를 출력
condition1 = tips['sex']=='Male'
condition2 = tips['smoker']=='Yes'

tips.loc[condition1 & condition2].sort_values(by='tip', ascending=False).head(10)

  • 팁을 5 이상, 10 이하로 낸 손님을 필터링
  • size가 3인 이하 손님을 필터링
  • 컬럼은 total_bill, sex, time만 나오도록 출력
condition1 = tips['tip']>=5
condition2 = tips['tip']<=10
condition3 = tips['size']<=3
tips.loc[condition1 & condition2 & condition3, ['total_bill','sex','time']]

 

조건부를 사용하는 numpy와 pandas에서의 where가 서로 다르다.

 

 

pandas의 where 역시 잘 쓰이지는 않지만 loc와 조건 필터링을 연결해서 사용할 수 있다.

✅ 팁을 2불 이상 낸 사람중에서 남자들만 검색해달라.

condition1 = (tips['tip']>=2 )
condition2 = (tips['sex']=='Male')
condition3 = (tips['size']==2)

tips.loc[condition1 & condition2 & condition3]

 

 

 

 

 

✅ 위의 조건에서 첫 번째 칼럼부터 tip 칼럼까지 추출

# 행 슬라이싱, 열 슬라이싱
tips.loc[condition1 & condition2 & condition3, :'tip']
tips.loc[condition1 & condition2 & condition3, 'total_bill':'tip']

 

 

✅ tip, smoker, size 칼럼만 뽑아서

tips.loc[condition1 & condition2 & condition3, ['tip','smoker','size']]
tips.loc[condition1 & condition2 & condition3].head(3) # loc로 접근
tips[condition1 & condition2 & condition3].head(3) # boolean indexing... 권장

 


 

DataFrame - iloc

loc앞에 i만 붙었다.

i는 index의 iloc와 다르게 iloc는 label이 들어갈 수 없다.

무조건 index로만 검색하는 기능, 따라서 마지막 인덱스 포함 안 됨

조건 필터링 할 때는 안 쓰이고 주로 슬라이싱 할 때 많이 사용됨 Numpy의 슬라이싱과 완전 동일한 기법

# 열거형 인덱싱에서는 마지막 인덱스 2는 포함 안 됨
tips.iloc[:2, [1,3,5]]

 

DataFrame- at, iat 

  • one row
  • one column

특정 인덱스 arr[ index, index ] 와 같이 특정 하나의 값 → 스칼라 값 

tips.head(4)
tips.at[ 3 , 'day' ] # 행은 3, 열은 day인 곳의 데이터 값
# Sun
tips.iat[3,4] # 인덱스로 지정해서 데이터 하나의 값
#'Sun'

 

where

  • Codition True/False로 판단할 수 있는 식
  • other condition을 만족하지 못하는 요소에 할당할 값
# 만약 조건이 True이면 그대로 출력, 그렇지 않으면 default 0
tips['tip'].where(tips['tip']>=2, 0).tail(10) # tip이 2불보다 클 때의 값
'''
235    0.00
236    0.00
237    0.00
238    4.67
239    5.92
240    2.00
241    2.00
242    0.00
243    3.00
244    0.00
Name: tip, dtype: float64
'''

# 만약 조건이 True이면 그대로 출력, 그렇지 않으면 default 10
tips['tip'].where(tips['tip']>=2, 10).tail(10) # tip이 2불보다 클 때의 값
'''
235    10.00
236    10.00
237    10.00
238     4.67
239     5.92
240     2.00
241     2.00
242    10.00
243     3.00
244    10.00
Name: tip, dtype: float64
'''

 

isin

파이썬 in 키워드와 유사

  1. 우리가 걸러내고 싶은 컬럼을 가져와서
  2. 리스트 안에다가 정의
  3. 이 부분 역시 loc와 연결

True, False로 반환하므로 loc() 함수의 조건부로 작동

sample = DataFrame({
    'name':['강씨', '이씨', '박씨'],
    'age':[33,44,55]
})
sample
condition4=sample['name'].isin(['강씨','이씨']) # 존재하면 True 반환
'''
0     True
1     True
2    False
Name: name, dtype: bool
'''
sample.loc[condition4]

 

copy() 함수

tips.head()

주소값이 다르다는 것은 다른 dataframe이라는 의미

tips_copy = tips.copy() # 복사본 생성,,, 새로운 변수에 할당
tips_copy.head()

# 메모리 주소값을 찍어보자
# id() 사용, 주소값이 같으면, 같은 객체 / 주소값이 다르면 다른 객체
id(tips), id(tips_copy)
# (1563743184256, 1563785736592)

 

copy 함수 사용하지 않고 재대입 하면 복사본이 아니라 같은 데이터를 생성하는 것

# 재대입
'''
카피본을 만들 때는 어떨 때?
분석을 하기 전, 특정한 방법이 검증되지 않아서 실험적으로
이 방법, 저 방법 여러 방버으로 시도를 해야 하는 경우
예를 들어서 누락 데이터에 대한 전략적인 처리..
여러가지 방법을 사용하면 다음에 성능이 가장 좋은 놈으로 채택
결과를 검증한 다음에 그걸 원본 데이터에 적용하는 방식을 말한다.
'''
tips2 = tips
id(tips), id(tips2)  # (1563743184256, 1563743184256) 주소값이 같다

 

원본을 훼손하지 않는 방법

tips_copy.loc[0, 'tip'] = 999
tips_copy.head(1)

tips.head(1)  # 원본을 훼손하지 않음

댓글