>>> import pandas as pd
exam = pd.read_excel("excel_exam.xlsx")
exam.head()
#exam에서 class 가 1인 경우만 추출
>>> exam['class'] == 1 #serise로 출력됨
>>> exam[exam['class'] == 1] #dataframe으로 출력됨
#math >= 50 인 경우만 출력
>>> exam[exam['math'] >= 50]
#방법1 (내가 생각한 방법)
>>> class1 = exam[exam['class'] == 1]
>>> class1[class1['math'] >= 50]
#방법2
>>> exam[(exam['class'] == 1) & (exam['math'] >= 50)]
>>> cond1 = exam['class'] == 1
cond2 = exam['math'] >= 50
exam[cond1 & cond2]
#방법3 : query()를 사용하여 추출
#query('') : 괄호 안의 조건에 대해 검색하여 조건에 맞는 데이터만 추출
>>> exam.query('math >= 50')
>>> exam.query('math >= 50 & english > 90') #'' 안에 '한 문장'이 들어간다
#df.query()를 이용하여 1반이면서 수학이 50점 이상인 경우 추출
>>> exam.query('class == 1 and math >= 50')
SyntaxError: Python keyword not valid identifier in numexpr query
#칼럼의 이름으로 'class'가 사용되어 에러
>>> exam.rename({'class' : 'nclass'}, axis = 1, inplace = True)
exam.query('nclass == 1 and math >= 50')
>>> exam.query('nclass in [1, 3, 5]') #1,3,5반 만 출력된다
#변수 in [ ] : for 문과 비슷하다, 변수의 값이 []에 입력한 목록에 해당되는지 확인
(in : '==' 역할)
'''
[1,2,3,4,5] in [1,3,5]
1 in [1,3,5]
2 in [1,3,5]
3 in [1,3,5]
4 in [1,3,5]
5 in [1,3,5]
6 in [1,3,5]
'''
>>> df = pd.DataFrame({'sex': ['F','M','F','M'],
'country' : ['Korea', 'China', 'Japan', 'USA']})
df
>>> df.query('sex == "F" and country == "Korea"') #따옴표 사용 유의
>>> exam
>>> exam.iloc[ : , [0,2,3]]
>>> exam.iloc[ : , 2: ]
>>> exam.loc[ : , ['math', 'english', 'science']]
>>> exam[:2] #인덱스 번호 2(0,1,2) -> 2행까지(인덱스 번호 0,1) 출력
#변수 제거하기 : df.drop(columns = '제거할 변수명')
>>> exam.drop(columns = 'math')
>>> exam.drop(['id', 'nclass'], axis = 1) #여러 변수 제거 -> []
① df.sort_values()
② df.sort_index()
#오름차순 정렬
>>> exam.sort_values(by = 'math')
#내림차순 정렬
>>> exam.sort_values(by = 'math', ascending = False)
>>> exam.sort_values(by = ['math', 'english'], ascending = False)
>>> df = exam.sort_values(['math', 'english'], ascending = False)
df
>>> df.sort_index()
#새로운 칼럼 total = math + english + science
#exam['total'] = exam['math'] + exam['english'] + exam['science']
>>> exam.assign(total = exam['math'] + exam['english'] + exam['science'])
>>> exam.head()
>>> exam.groupby('nclass')
>>> list(exam.groupby('nclass')) #5개의 그룹(dataframe)으로 나뉜다
>>> exam.groupby('nclass').min()
#exam의 20개 데이터 -> groupby('nclass')로 5개 그룹으로 쪼갬 -> 각각의 그룹에 min() 함수 적용
#'nclass'가 인덱스로 되었다
>>> exam.groupby('nclass').min()['math'] #serise로 출력
>>> exam.groupby('nclass').min()[['math']] #dataframe으로 출력
>>> exam.groupby('nclass').min()[['math', 'science']]
#다른 표기법
>>> list(exam[['nclass', 'math', 'science']].groupby('nclass'))
>>> exam[['nclass', 'math', 'science']].groupby('nclass').min()
groupby() 에 여러 변수를 지정하면 집단을 나눈 다음 다시 하위 집단으로 나눌 수 있다
>>> pip install pydataset
>>> import pydataset
>>> mpg = pydataset.data("mpg")
mpg
#drv와 class로 그룹을 짓고, 각 그룹별 cty의 min 값 구하기
>>> mpg.groupby(['drv', 'class']).min()[['cty']] #인덱스가 drv, class 2개
하나의 함수에만 적용할 때는 groupby와 agg의 결과가 동일하지만, 2개 이상의 함수에 적용할 때는 agg()를 사용해야한다
agg()는 전체를 요약한 값을 구하기 보다는 groupby()에 적용해 집단별 요약값을 구할 때 사용한다
df.groupby()에 변수를 지정하면 변수의 범주별로 데이터를 분리한다
여기에 agg()를 적용하면 집단별 요약 통계량을 구한다
#mpg.groupby(['drv', 'class']).min()
>>> mpg.groupby(['drv', 'class']).agg(min)
>>> mpg.groupby(['drv', 'class']).agg(min)[['cty', 'hwy']]
#agg() 대신에 apply()를 사용할 수도 있다
>>> mpg.groupby(['drv', 'class']).apply(min)
#2개의 함수 적용 -> agg() 사용
>>> mpg.groupby(['drv', 'class']).agg([min, max])
>>> mpg.groupby(['drv', 'class']).agg([min, max])[['cty']]
#칼럼마다 다른 함수 적용
>>> mpg.groupby(['drv', 'class']).agg({'cty' : min, 'hwy' : max})
#집단별 요약 통계량 구하기
>>> mpg.groupby(['drv', 'class']).agg(mean_cty = ('cty', 'mean'))
#groupby로 분리 후 cty 평균값 구하기
#여러 요약 통계량 한번에 구하기
>>> mpg.groupby(['drv', 'class']).agg(mean_cty = ('cty', 'mean'),
sum_cty = ('cty', 'sum'))
기존 데이터에 변수(열)를 추가하는 것
>>> test1 = pd.DataFrame({'id' : [1,2,3,4,5], 'midterm' : [60,80,70,90,85]})
test2 = pd.DataFrame({'id' : [1,2,3,4,5], 'final' : [70,83,65,95,80]})
>>> test1
>>> test2
>>> pd.merge(test1, test2) #id를 기준으로 합쳐서 할당된다
>>> test1 = pd.DataFrame({'id' : [1,2,3,4,5], 'midterm' : [60,80,70,90,85]})
test2 = pd.DataFrame({'id' : [1,2,3,6,7], 'final' : [70,83,65,95,80]})
pd.merge(test1, test2) #id 값이 같은 데이터만 합쳐져서 나온다
>>> pd.merge(test1, test2, how = 'outer') #'outer' : 합집합의 의미
>>> pd.merge(test1, test2, how = 'left')
>>> pd.merge(test1, test2, how = 'right')
>>> exam
#teacher 변수 추가
>>> teacher = pd.DataFrame({'nclass' : [1,2,3,4,5],
'teacher' : ['choi','park','kim','lee','han']})
>>> teacher
>>> pd.merge(exam, teacher)
#on = '변수명' : 데이터를 합칠 때 기준으로 삼을 변수명
>>> pd.merge(exam, teacher, on = 'nclass')
기존 데이터에 변수(행)를 추가하는 것
>>> pd.concat([test1, test2])
>>> pd.concat([test1, test2], axis = 1) #옆에 붙었다
>>> pd.concat([test1, test2], axis = 1, join = 'inner')
#join = 'inner' : inner -> 교집합, '인덱스 번호를 기준으로' 합친다는 의미
>>> test1 = pd.DataFrame({'id' : [1,2,3,4,5], 'midterm' : [60,80,70,90,85]})
test2 = pd.DataFrame({'id' : [1,2,3,6,7], 'final' : [70,83,65,95,80]})
#test2에 'i'라는 변수 추가
>>> test2['i'] = [0, 1, 2, 4, 5]
#'i'를 test2의 인덱스 번호로
>>> test2.set_index('i', inplace = True)
>>> test2
>>> pd.concat([test1, test2], axis = 1, join = 'inner')
#test1과 test2의 겹치는 인덱스 번호로만 합쳐진다 (inner -> 교집합)
>>> test3 = test2.rename({'final' : 'midterm'}, axis = 1)
test3
>>> pd.concat([test1, test3])
>>> g = pd.concat([test1, test3])
>>> g.groupby('id').mean()
>>> g.groupby('id').min()
결측치 : 누락된 값, 비어있는 값
이상치 : 정상 범위에서 크게 벗어난 값
결측치나 이상치가 있으면 함수가 적용되지 않거나 분석 결과가 왜곡될 수 있다
>>> import numpy as np
>>> exam
>>> exam.iloc[0,2] = np.nan
>>> exam
>>> exam.iloc[1,3] = np.nan
exam.iloc[2,4] = np.nan
exam
>>> df = exam.copy()
pd.isna(df)
#결측치 빈도 확인 - 데이터에 결측치가 총 몇개 있는지 출력
>>> pd.isna(df).sum()
#모든 변수에 결측치 없는 데이터 추출
>>> df.dropna()
df
#결측치 있는 행 제거하기 : subset = ['변수명']
>>> df.dropna(subset = 'math')
#pandas에서는 Na 값이 있어도 알아서 그 값을 제외하고 계산해준다
>>> df['math']
>>> df['math'].mean()
>>> np.mean(df.math)
>>> df.apply(np.mean)
결측치를 다른 값으로 대체하면 데이터가 손실되어 분석 결과가 왜곡되는 문제를 보완할 수 있다
>>> m = df['math'].mean()
m
>>> df['math'].fillna(m)
>>> df
>>> df['math'] = df['math'].fillna(m)
df #math열에서의 Na 값이 math의 평균값으로 대체되었다
>>> df['english']
>>> df['english'].fillna(method = 'ffill') #ffill -> foward fill
>>> df['english'].fillna(method = 'bfill', inplace = True) #bfill -> back fill
df
>>> s = df['science'].mean()
df['science'].fillna(s, inplace = True)
df
결측치 : 누락된 값, 비어있는 값
이상치 : 정상 범위에서 크게 벗어난 값
결측치나 이상치가 있으면 함수가 적용되지 않거나 분석 결과가 왜곡될 수 있다
#이상치 만들기
>>> df.iloc[0,2] = 10
df.iloc[1,3] = 10
df
>>> import seaborn as sns
sns.boxplot(data = df, x = 'math')
>>> sns.boxplot(data = df, y = 'math')