본문 바로가기

데이터 분석

11 - 코테

pandas의 자료구조 Series와 DataFrame 

 

엑셀의 내부 data 가공 -> pandas 

전체적인 표, 전체적인 data를 읽어오고 내가 원하는대로 가공할 수 있다. 

 

pandas는 핵심라이브러리로, 고유한 자료구조인 Series와 Dataframe으로 빅데이터 분석에 높은 수준의 퍼포먼스를 발휘.

 

 

 

 

Series : 각 열(column)의 단위 

Dataframe : 각 열 단위(Series)가 모여 된 하나의 표를 Dataframe

index : Series, Dataframe을 생성하면 인덱싱 번호가 따라다닌다. 인덱스는 Series가 아니다. 위 이미지에는 숫자로 되어있지만 내가 원하는 인덱스 형태로 변경할 수 있다. 

 

 

 

Series와 Dataframe는 numpy의 1차원과 2차원 array와 매우 유사하다. 

 

 

pandas를 사용하기에 앞서 numpy와 pandas 패키지를 모두 import 해야한다.

 

import numpy as np
import pandas as pd

 

Series를 정의할 때, pd.Series()를 이용하는데 python의 list나 numpy의 array가 인자로 입력된다.

 

obj = pd.Series([4,7,-5,3])
obj

 

series를 확인해보면 index와 values가 동시에 확인된다.

이 때, 리스트의 성분 갯수 = index의 갯수 

 

 

 

리스트는 여러개의 데이터를 하나로 묶는다.

,콤마와 [ ] 대괄호를 사용한다. 

 


 

문제 1 - 1 

2023년 1월 29일, 자신의 이름, MBTI, 핸드폰 번호 뒷자리를 리스트로 저장하고 그것을 Series의 형태로 변환하여 출력하세요.

# Series의 형태는 python의 list나 numpy의 array가 인자이다.
# 1. 리스트 데이터 형성 

list_data = ['2023-01-29','우유희','isfp','01085181806']
sr = pd.Series(list_data)
print(sr)

 

 

 

 


 

 

 

 

 

딕셔너리 

 

{Key1: Value1, Key2: Value2, Key3: Value3, ...}

 

dic = {'name': 'pey', 'phone': '010-9999-1234', 'birth': '1118'}

 

 

 

 

 

 

문제 1 - 2

딕셔너리를 사용하여 다음의 DataFrame 모양을 만들어 출력하세요.(DataFrame은 df로 저장해주세요)

exam_data = {'국어':[95,85,80],'수학':[100,85,90],'영어':[90,90,80],'탐구':[80,100,90]}
df = pd.DataFrame(exam_data, index = ['사람1','사람2','사람3'])
df

 

 

 

 

 

 


 

 

열 삭제하기 

1. drop 함수 이용하기 

df.drop(['삭제할 열 이름1','삭제할 열 이름2',...], axis =1)

 

 

inplace = True or False?

inplace = True : 기존 데이터 프레임을 변경하기 

inplace = False : copy를 return

 

 

 

 

문제 [1-3] - 3점

위에서 만들어진 df에서 '탐구'열(column)을 삭제하고 출력하세요.

 

df.drop('탐구', axis = 1, inplace = True)
df

 

 

 

 

 

axis = 1 빼먹지 말기 

삭제할 열이 여러개가 아니라면 리스트 붙여줄 필요없음

inplace = True를 하거나 =로 할당하지 않는다면 데이터프레임에 적용되지 않음

 

 

 

 

 


 

 

데이터 프레임에 열 추가 

['추가하고자 하는 열의 이름'] = ''

 

 

round() 함수 

주어진 숫자를 지정한 소수점 자릿수에 맞춰 반올림하는 역할

round(3.141592, 2)
3.14

 

 

 

문제 [1-4] - 4점

df에 국어, 수학, 영어 3과목의 평균 점수를 나타내는 '평균' 열(column)을 추가하여 출력하세요.(소수점 세번째 자리에서 반올림하여 소수점 둘째자리까지만 나타내세요)

 

df['평균'] = round((df['국어'] + df['수학'] + df['영어']) / 3, 2)
df

 

 

 


 

판다스 데이터프레임에 새로운 열을 추가하는 방법 

 

간단한 할당 

df['newcolumn'] = [1,2,3,4]

 

 

append()

리스트에서 데이터를 추가하는 방법

맨 뒤에 인자 추가 

리스트 이름.append(데이터 값)

 

 

 

 

문제 [1-5] - 7점

'평균'열에 나온 점수를 기준으로 등급으로 변환한 '등급'열을 추가하여 출력하세요(95점 이상 A+, 90점 이상 A, 85점 이상 B+, 80점 이상 B 입니다.)

 

grades = []
# 빈 리스트 만들어주기 

for i in df['평균']:
    if i >= 95:
        grades.append('A+')
    elif i >= 90: 
        grades.append('A')
    elif i >= 85:
        grades.append('B+')
    else :
        grades.append('B')

df['등급'] = grades 
# 데이터 프레임에 열 추가 
df

 

 

 

i를 통해 df['평균']을 순환시킨다는 점 잊지말기 

for i in df['평균] 다음에 : 이거 붙이는거 까먹지 말기 

 

'elif'와 'else'는 조건문에서 다른 역할을 수행한다.

 

- elif : 여러개의 조건을 순차적으로 검사하고, 처음으로 참이 되는 조건의 코드블록을 실행, if 다음에 나오며 여러개 사용, 만약 앞의 조건이 거짓이면 이 조건을 확인해봐.

- else : 만약 앞의 모든 조건이 거짓이면 이 코드를 실행해, 모든 이전 조건이 거짓인 경우 실행되며 마지막에 사용된다, if 또는 elif 다음에 나오며 단 한번만 사용된다. 

 

 

 


 

 

 

python 을 가지고 분석에 활용한다고 했을 때 데이터 전처리에 Numpy와 Pandas library를 많이 사용한다.

특히 행과 열로 구성이 되어있는 DataFrame type 데이터를 입력, 처리, 조작할 때 pandas 가 매우 강력하고 편리하다.

 

 

 

 

1. csv 파일 불러오기 : read_csv()

import 로 pandas library를 호출한 다음에 read_csv() 함수에 파일 경로와 파일 이름을 적어주면 된다.

 

import pandas as pd
csv_test = pd.read_csv('C:/Users/Administrator/Documents/Python/test_csv_file.csv')

 

 

2. 앞의 행 출력 

df.head()

 

 

문제 [2-1] - 3점

spotify.csv 파일을 불러오고 data 변수에 저장하여 맨 위에 3개 행을 출력하세요.

 

data = pd.read_csv('spotify.csv')
data.head(3)

 

 

 

그냥 head만 쓰면 5개의 행이 출력되므로 .head(3) 붙이기 

 

 

 


 

counts()

문자열에서 주어진 요소의 총 개수 

변수.count(찾는 요소)

 

변수.value_counts()

열의 각 값(value)에 대한 모든 발생 횟수를 반환합니다.

 

 

 

문제 [2-2] - 3점

data의 열(column) 중에서 'Artist'열에서 고유값의 종류와 갯수를 확인할 수 있는 함수를 쓰고 다음과 같이 출력하세요.

 

data['Artist'].value_counts()

 

 

 

 

 


 

 

 

문제 [2-3] - 5점

'Artist'열에서 아티스트가 BTS인 행들을 찾아 출력하세요.

 

data[data['Aritist'] == 'BTS']

 

 


 

 

히스토그램

 

bins : x축 데이터에 해당되는 계급의 구간 수 (기본 값 : 10)

 

pandas.DataFrame.plot.hist()

pandas.Series.plot.hist()

 

 

 

문제 [2-4] - 7점

'tempo' 열에 대한 히스토그램을 그려주세요.

(구간은 총 10개로 나누고 그림 사이즈는 (10,5)로 설정하여 나타내어 주세요)

 

data['tempo'].plot(kind = 'hist', bins = 10, figsize = (10,5))

 

 

 

hist에 '따옴표' 붙이기

 

 

 


 

 

~이면서 = & 

 

 

 

문제 [2-5] - 7점

'Artist'가 BTS이면서 'Tempo'가 평균 이상인 것들을 다음과 같이 출력하세요.

(열(column)은 Rank, Track Name, Artist, tempo만 나오도록 하세요)

 

 

 

 

1. 평균 내기 
mmm = data['Tempo'].mean()
data[(data['Tempo']>=mmm) & (data['Artist'] == 'BTS')][['Rank','Track Name','Artist', 'tempo']]

 

 

 


 

 

 

loc 개념 정리 

인덱싱은 데이터프레임에서 적용될 수 있다.

판다스에서는 특정 행이나 열 

 

df.loc[행 인덱싱 값, 열 인덱싱 값]

 

 

 

문제 [3-1] - 2점

C02, C03 강의의 Class, Year 열(column)을 출력하세요.

 

df1[['Class','Year']].loc[['C02','C03']]

 

 

 

loc은 행 레이블을 기반으로 행을 선택하는데 사용되는 pandas의 메서드입니다. 

열을 선택할 때는 [['Class','Year']] 와 같이 사용하며, 행을 선택할때는 loc[['C02','C03']] 와 같이 사용합니다.

이는 행과 열을 명확히 구분하기 위한 문법적 차이입니다. 

 

 

 

 


 

 

 

문제 [3-2] - 3점

Year 열(column)에서 년도가 2018년도 혹은 2019년도에 개설된 Class 를 출력하세요.

 

df1['class'][(df1.Year == 2018)|(df1.Year == 2019)]

 

 

 

 


 

 

문제 [3-3] - 5점

강의 별 price 에 대한 세로형 막대 그래프를 출력하세요.

 

 

df1['price'].plot(kind = 'bar', figsize = (10,5))

 

 

 

 

 

 


 

 

pandas apply 함수와 lambda 설명 

 

데이터프레임을 조작하다보면 내가 정의해놓은 함수에 따라 전체 데이터프레임이나 특정한 column의 값들을 일괄적으로 변경하기를 원할 수 있습니다. 

 

이런 경우에 어떤 pandas 메소드를 활용해야 하는가.

 

pandas에서는 특정 행 혹은 전체 데이터프레임에 함수를 적용할 수 있다.

예를 들어 df(x): 처럼 함수로 나타낸 코드의 return 값을 모든 데이터프레임에 적용하고 싶은 것이다. 

= pandas의 apply 함수 

 

 

 


 

 

 

numpy와 pandas 를 불러온 뒤, 간략한 테스트용 데이터프레임을 생성한다.

 

import numpy as np
import pandas as pd

df = pd.DataFrame([[4,9],[1,4],[5,6]], columns = ['A','B'])

 

 

1. a컬럼의 값에 내가 정해놓은 함수 return 값을 일괄적으로 적용하기 (컬럼 일괄 변경)

2. df라는 데이터프레임 전체에 내가 정해놓은 함수return 값을 일괄적으로 적용하기 (dataframe 일괄 변경)

 

위의 두가지는 파이썬의 기본적인 함수 정의 구문 (def)을 통해서 함수를 정의한 뒤에,

pandas의 apply를 활용하여 일괄 적용할 수 있다. 

 

 

1. column 일괄 변경 

특정 컬럼에 대해서 내가 정의한 함수를 적용 

우선 함수 정의하기 

 

모든 값에 1을 더하는 코드 작성 

함수(plus_one) 정의 

 

def plus_one(x):
    x+=1
    return x

 

 

 

해당 함수를 우리가 기존에 정의한 데이터프레임 중 A컬럼에 대해 적용하려면 아래와 같이 pandas의 apply 함수를 적용 

데이터프레임["컬럼"].apply(함수명)

df['A'].apply(plus_one)

 

 

물론 해당 결과는 시리즈로 나올 겁니다.

왜냐면 특정 컬럼만을 적용하였으니 데이터프레임이 아닌 시리즈로 나오는게 정상이기 때문입니다. (시리즈와 컬럼은 같은 개념)

그러나 기존의 데이터프레임은 아직 바뀐게 아닙니다.

이것을 기존의 데이터프레임에 적용하고 싶으면 다시 객체를 해당 컬럼에 할당시키면 됩니다. 

 

df['A'] = df['A'].apply(plus_one)

 

 

 

 


 

 

 

문제 [3-4] - 10점

priceLevel 열(column)을 추가하고 Price 열(column)의 값이 200보다 크거나 같으면 'High', 200 보다 작으면 'Low'를 할당하여 출력하세요.

이 때, get_priceLevel() 함수를 생성하여 priceLevel열의 값들을 추가하세요.

 

def get_priceLevel(Price):
    if Price >= 200:
        return 'High'
    else:
        return 'Low'

df1['priceLevel'] = df1['Price'].apply(get_priceLevel)
df1

 

 

 

 


 

 

문제 [4-1] - 2점

titanic.csv 를 titanic 변수에 저장하여 불러와주세요.

 

titanic = pd.read_csv('titanic.csv')
titanic.head()

 

 

 


 

axis  = 0 (index)은 행을 따라 작동

axis = 1 열 

 

 

 

결측치 처리 순서 

1. 데이터 프레임 준비 - 생성, 파일 읽기 등 

2. 데이터 프레임 결측치 확인 - isna(),  isna().sum()

3. 데이터 프레임 결측치 제거 1 (행 또는 열이 모두 NA인 경우)

4. 데이터 프레임 결측치 대체 - fillna()

 

 

isna() 

isna() - 값이 NA(결측치)이면 True, 아니면 True 

 

isna()를 이용하여 결측치 유무 확인 가능하지만, 눈에 안 들어온다. 

 

df.isna().sum()   -   행 별 (row) NA 개수 확인 

df.isna().sum(axis = 1)   -   열 별 (column) NA 개수 확인 

 

 


 

 

상위 N행 살펴보기 

.head() 함수는 불러온 데이터의 상위 5개의 행을 출력합니다.

.tail() 의 경우 하위 5개의 행을 출력합니다.

 

 

(행,열) 크기를 확인하기

.shape()

데이터의 (행, 열) 크기를 확인할 수 있다. 

 

 

정보 확인하기

.info() 

데이터에 대한 전반적인 정보 

df를 구성하는 행과 열의 크기, 컬렴명, 컬럼을 구성하는 값의 자료형 

 

 

요약 통계량 확인하기   

.describe()

컬렴별 요약 통계량 - mean(), std(), max()

 

 

 

 

 

 

 

문제 [4-2] - 2점

결측값을 확인하세요.

titanic.info()

titanic.isna().sum()

 

 

 

 


 

판다스 매개변수 axis의 의미 

판다스를 사용하다 보면 평균 계산, 데이터프레임 열이나 행 삭제 작업 등을 할 때 axis (축) 을 지정해야 합니다. 

 

복습) 

axis = 0 (index)는 행을 따라 동작합니다.

axis = 1 (columns)는 열을 따라 동작합니다.   =    각 행의 모든 컬럼에 대해서 동작 

 

 

 

예제로 사용할 DataFrame 을 만들겠습니다. 

df = pd.DataFrame({'name':[''KIM', 'LEE', 'SMITH','BROWN', 'MILLER'],
'age':[24, 32, 43, 24, np.nan], 'height':[178, 168, 171, 185, 176],
'sex':['M', 'F', 'F', 'M', 'F']})

df

 

 

df.drop([1,2], axis = 0)
# 1행과 2행을 삭제하시오 

df.drop(['age','height'], axis =1)
# 'age'열과 'height'열을 삭제하시오

df[['age','height']].mean(axis = 0)
# 'age'행과 'height'행을 삭제하시오

df[['age','height']].mean(axis = 1)
# 'age'열과 'height'열의 평균을 구하시오

 

 

 

 

 

문제 [4-3] - 4점

변수 Ticket, Cabin을 제거하세요.

titanic.drop(['Cabinet','Ticket'], axis = 1, inplace = True)

titanic.info()

 

 

 


 

 

 

결측값 대체 

df.dropna() 를 사용하여 NaN값을 삭제한다. 

train = train.dropna()

 

 

NaN 값 0으로 채우기 

fillna()를 사용하여 NaN 값을 0으로 채운다.

test = test.fillna(0)

 

 

NaN값 평균치로 채우기 

filna를 사용하여 평균치로 NaN 값을 채운다.

 

 

 

문제 [4-4] - 6점

age 변수의 결측값을 중간값으로 채워넣으세요.

 

titanic['Age'].fillna(titanic['age'].median(), inplace = True)
titanic.info()

 

 

 


 

 

 

문제 [4-5] - 6점

'Embarked' 변수의 결측값을 'S'로 채워넣으세요.

 

titanic['Embarked'] = titanic['Emabarked'].fillna('S')
titanic.info()

 

 

 


 

 

 

문제 [5-1] - 3점

인구수예제.xlsx를 data_p로 불러온 후, 위에서부터 5행을 출력하세요.

 

data_p = pd.read_excel('인구수예제.xlsx')
data_p.head()

 

 

 

 


 

 

판다스 .groupby()

그룹별로 분할하여 별도의 데이터 처리 혹은 그룹별 통계량 확인 

 

1. 그룹별 통계량 확인 

데이터프레임에 .groupby(컬럼) + 통계함수 

# 평균 (mean)
df.groupby('sex').mean()

# 분산 (var)
df.groupby.('sex').var()

 

.agg() 에 적용할 수 있는 통계함수 문자열 표 (다중 통계량)

df.groupby('sex').agg(['mean','var'])

 

 

 

 

 

문제 [5-2] - 5점

연도별/도시별 총인구수를 구하세요.

data_p.groupby(['연도','도시'])['총인구'].sum()

 

 

 


 

 

문제 [5-3] - 7점

도시/자치구별 평균 남자인구수와 여자인구수를 구하세요.

 

data_p.groupby(['도시','자치구'])[['남자인구','여자인구']].mean()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고 : https://ybworld.tistory.com/40, https://koreadatascientist.tistory.com/115,https://hogni.tistory.com/49,https://teddylee777.github.io/pandas/pandas-groupby/