PYTHON LIBRARY/Numpy & Pandas 실습

Pandas 실습 문제 : 데이터 불러오기 index_col, 인덱스 세팅 set_index, 통계 함수 복습, value_counts() 활용법

신강희 2024. 4. 14. 13:45
728x90

# 기초개념에서 배운것들을 실습문제를 통해서 복습

winemag-data-130k-v2.csv 파일을 reviews 로 읽는다.

 

# import

import pandas as pd

 

pd.read_csv('../data/winemag-data.csv')

와인 평가 리뷰에 대한 데이터

ㄴ Unnamed: 0 라고 뜨는것은 인덱스가 컬럼으로 올라온것이라 밑으로 네려줘야함

 

# index_col= 0 자리에 'Unnamed: 0' 로 적어줘도됨

pd.read_csv('../data/winemag-data.csv' , index_col= 0)

 

# 변수로 저장

df = pd.read_csv('../data/winemag-data.csv' , index_col= 0)

 

문제) 인덱스를 title 컬럼으로 셋팅한다.

 

# 변수명.set_index('셋팅할 컬럼명', 저장 여부) 사용

df.set_index('title', inplace=True)

ㄴ inplace=True는 변수에 바로 저장한다는 파라미터 명령어

 

 

문제) 먼저 데이터가 비어있느것이 있는지 확인한다.

 

df.isna()

ㄴ True인 데이터가 있으므로 비어있다는걸 알수 있음.

 

# 컬럼 별로 비어있는 개수를 보고싶으면?

df.isna().sum()

country                     63
description                  0
designation              37465
points                       0
price                     8996
province                    63
region_1                 21247
region_2                 79460
taster_name              26244
taster_twitter_handle    31213
variety                      1
winery                       0
critic                       0
dtype: int64

 

문제) 그리고나서, 가격이 없는 데이터는 빼고, 데이터셋을 가져온다.

 

# 가격 컬럼에서 .notna() 빈칸이 있는 행을 제외하고 불러옴

df['price'].notna()

title
Nicosia 2013 Vulkà Bianco  (Etna)                                                                        False
Quinta dos Avidagos 2011 Avidagos Red (Douro)                                                             True
Rainstorm 2013 Pinot Gris (Willamette Valley)                                                             True
St. Julian 2013 Reserve Late Harvest Riesling (Lake Michigan Shore)                                       True
Sweet Cheeks 2012 Vintner's Reserve Wild Child Block Pinot Noir (Willamette Valley)                       True
                                                                                                         ...  
Dr. H. Thanisch (Erben Müller-Burggraef) 2013 Brauneberger Juffer-Sonnenuhr Spätlese Riesling (Mosel)     True
Citation 2004 Pinot Noir (Oregon)                                                                         True
Domaine Gresser 2013 Kritt Gewurztraminer (Alsace)                                                        True
Domaine Marcel Deiss 2012 Pinot Gris (Alsace)                                                             True
Domaine Schoffit 2012 Lieu-dit Harth Cuvée Caroline Gewurztraminer (Alsace)                               True
Name: price, Length: 129971, dtype: bool

 

# loc 를 사용하여 해당 데이터를 가져와 df_price 변수로 따로 저장

df_price = df.loc[df['price'].notna() , ]

 

# 진짜 비어있지 않은지 확인

df_price.isna().sum()

country                     59
description                  0
designation              34779
points                       0
price                        0
province                    59
region_1                 19575
region_2                 70683
taster_name              24496
taster_twitter_handle    29416
variety                      1
winery                       0
critic                       0
dtype: int64

ㄴ price 컬럼은 0인것을 보아 비어있는 데이터가 없는것을 확인할수 있다.

 

문제) 리뷰에 새로운 컬럼 critic 만들고, everyone 이라고 값 넣는다.

 

# 반복문 사용해서 리스트 지정해서 넣어줄 필요없이, pandas를 이용하면 문자열만 적어줘도 된다.

# df['생성할 컬럼명'] = '그안에 넣어줄 데이터'

df['critic'] = 'everyone'

 

문제) 리뷰의 포인트 컬럼은 수치로 되어있다. 이 컬럼의 기초통계데이터를 확인하시오. (평균, 최대 최소 등)

 

# points가 진짜 수치인가 확인

df.info()

<class 'pandas.core.frame.DataFrame'>
Index: 129971 entries, Nicosia 2013 Vulkà Bianco  (Etna) to Domaine Schoffit 2012 Lieu-dit Harth Cuvée Caroline Gewurztraminer (Alsace)
Data columns (total 13 columns):
 #   Column                 Non-Null Count   Dtype  
---  ------                 --------------   -----  
 0   country                129908 non-null  object 
 1   description            129971 non-null  object 
 2   designation            92506 non-null   object 
 3   points                 129971 non-null  int64  
 4   price                  120975 non-null  float64
 5   province               129908 non-null  object 
 6   region_1               108724 non-null  object 
 7   region_2               50511 non-null   object 
 8   taster_name            103727 non-null  object 
 9   taster_twitter_handle  98758 non-null   object 
 10  variety                129970 non-null  object 
 11  winery                 129971 non-null  object 
 12  critic                 129971 non-null  object 
dtypes: float64(1), int64(1), object(11)
memory usage: 17.9+ MB

ㄴ Dtype이 int인것 확인

 

# 평균

df['points'].mean()

88.44713820775404

 

# 최대값

df['points'].max()

100

 

# 최소값

df['points'].min()

80

 

# .describe() 로 한번에 처리해서 볼수도 있다.

df['points'].describe()

count    129971.000000
mean         88.447138
std           3.039730
min          80.000000
25%          86.000000
50%          88.000000
75%          91.000000
max         100.000000
Name: points, dtype: float64

 

문제) taster_name 컬럼은 사람 이름으로 되어있다. 몇명의 사람들이 평가를 한것인까?

 

# 전체 행(데이터)은 몇개인가? => 129971

df.shape

(129971, 13)

 

# 유니크한 항목은 뭐뭐가 있나?

df['taster_name'].unique()

array(['Kerin O’Keefe', 'Roger Voss', 'Paul Gregutt',
       'Alexander Peartree', 'Michael Schachner', 'Anna Lee C. Iijima',
       'Virginie Boone', 'Matt Kettmann', nan, 'Sean P. Sullivan',
       'Jim Gordon', 'Joe Czerwinski', 'Anne Krebiehl\xa0MW',
       'Lauren Buzzeo', 'Mike DeSimone', 'Jeff Jenssen',
       'Susan Kostrzewa', 'Carrie Dykes', 'Fiona Adams',
       'Christina Pickard'], dtype=object)

ㄴ 일일이 새보면 20명인것을 알수 있다.

 

# 자동으로 유니크한 항목의 갯수 확인 nunique()

df['taster_name'].nunique()

19

ㄴ 총 19명의 테스터가 평가한것 확인

 

## 해당 결과가 다른 이유는 unique() 함수는 빈칸인 nan 항목도 데이터로 치부하여 개수를 함께 카운트하기때문이다.

## nunique()는 default로 dropna=True 속성을 가지고 있어서 nan 항목을 제외하고 보여준다.

## 만약 unique() 함수로 nan을 제외하고 보고싶다면 미리 사전에 dropna이나 fillna로 데이터를 지우거나 채우고 실행하면 된다.

## 반대로 nunique()로 nan을 포함하여 보고 싶다면 nunique() 파라미터 안에 dropna=False를 넣으면 nan을 포함하여 카운트 한다. (but, 해당 방법은 nunique에서만 사용가능하고 unique함수 파라미터 안에는 dropna= 를 직접적으로 받지를 못해서 번거롭지만 먼저 dropna로 데이터에서 뺀후 실행하여야 한다.)

 

문제) 테스터들의 이름을 전부 확인하시오

 

# 상단에서 설명한것처럼 dropna를 먼저 사용하여 제외하고 unique 실행

df['taster_name'].dropna().unique()

array(['Kerin O’Keefe', 'Roger Voss', 'Paul Gregutt',
       'Alexander Peartree', 'Michael Schachner', 'Anna Lee C. Iijima',
       'Virginie Boone', 'Matt Kettmann', 'Sean P. Sullivan',
       'Jim Gordon', 'Joe Czerwinski', 'Anne Krebiehl\xa0MW',
       'Lauren Buzzeo', 'Mike DeSimone', 'Jeff Jenssen',
       'Susan Kostrzewa', 'Carrie Dykes', 'Fiona Adams',
       'Christina Pickard'], dtype=object)

ㄴ 세어보면 19명인것을 알수 있다.

 

# size를 활용해서 갯수를 비교해 보자

df['taster_name'].dropna().unique().size

19

 

df['taster_name'].unique().size

20

 

### 그러므로 카테고리컬 데이터의 명칭을 확인할때는 비어있는 데이터가 없는지 꼭 확인작업이 필요!!

 

문제) 각 테스터들은, 각각 몇개의 와인을 테스트 했는지 확인하시오. ( 테스터 이름, 갯수 )

 

# (1) .groupby를 활용하여 확인 가능

# 각테스터 네임별로 같은 테스터 네임 컬럼을 참고해서 데이터가 몇개씩인지 보면 데이터 갯수를 확인할수 있음
df.groupby('taster_name')['taster_name'].count()

taster_name
Alexander Peartree      415
Anna Lee C. Iijima     4415
Anne Krebiehl MW       3685
Carrie Dykes            139
Christina Pickard         6
Fiona Adams              27
Jeff Jenssen            491
Jim Gordon             4177
Joe Czerwinski         5147
Kerin O’Keefe         10776
Lauren Buzzeo          1835
Matt Kettmann          6332
Michael Schachner     15134
Mike DeSimone           514
Paul Gregutt           9532
Roger Voss            25514
Sean P. Sullivan       4966
Susan Kostrzewa        1085
Virginie Boone         9537
Name: taster_name, dtype: int64

 

# (2) .value_counts() 활용
df['taster_name'].value_counts()

taster_name
Roger Voss            25514
Michael Schachner     15134
Kerin O’Keefe         10776
Virginie Boone         9537
Paul Gregutt           9532
Matt Kettmann          6332
Joe Czerwinski         5147
Sean P. Sullivan       4966
Anna Lee C. Iijima     4415
Jim Gordon             4177
Anne Krebiehl MW       3685
Lauren Buzzeo          1835
Susan Kostrzewa        1085
Mike DeSimone           514
Jeff Jenssen            491
Alexander Peartree      415
Carrie Dykes            139
Fiona Adams              27
Christina Pickard         6
Name: count, dtype: int64

ㄴ .groupby의 경우 어떤 컬럼을 참고하여 다른 컬럼의 데이터를 보고싶을때 유용하고, 한개의 컬럼만 가지고 비교하면 될경우에는 value_counts()가 가장 효율적

 

문제) 리뷰의 포인트의 평균을 구하고, 리뷰의 포인트값이, 평균보다 큰 데이터 (즉, 평가가 좋은 와인) 만 가져오시오.

 

# 평균을 구하여

df['points'].mean()

88.44713820775404

 

# 평균보다 높은 데이터를 호출

df['points'] > df['points'].mean()

title
Nicosia 2013 Vulkà Bianco  (Etna)                                                                        False
Quinta dos Avidagos 2011 Avidagos Red (Douro)                                                            False
Rainstorm 2013 Pinot Gris (Willamette Valley)                                                            False
St. Julian 2013 Reserve Late Harvest Riesling (Lake Michigan Shore)                                      False
Sweet Cheeks 2012 Vintner's Reserve Wild Child Block Pinot Noir (Willamette Valley)                      False
                                                                                                         ...  
Dr. H. Thanisch (Erben Müller-Burggraef) 2013 Brauneberger Juffer-Sonnenuhr Spätlese Riesling (Mosel)     True
Citation 2004 Pinot Noir (Oregon)                                                                         True
Domaine Gresser 2013 Kritt Gewurztraminer (Alsace)                                                        True
Domaine Marcel Deiss 2012 Pinot Gris (Alsace)                                                             True
Domaine Schoffit 2012 Lieu-dit Harth Cuvée Caroline Gewurztraminer (Alsace)                               True
Name: points, Length: 129971, dtype: bool

 

# 해당 데이터를 행렬로 가져온다.

df.loc[ df['points'] > df['points'].mean() , ]

 

다음 실습 문제로 계속

반응형