
2. 판다스(Pandas)
2-12. 그룹으로 묶기
DataFrame(df):

groupby(): data를 그룹으로 묶음
# 소속사를 기준으로 묶어 갯수를 파악하려는 경우
df.groupby('소속사').count()

#'그룹'을 기준으로 묶어 수치값에 대한 '평균'을 파악하려는 경우
(여기서 파악할 수 있는 수치값은 '키', '브랜드평판지수'이다.)
df.groupby('그룹').mean()

#'성별'을 기준으로 묶어 수치값에 대한 '평균'을 파악하려는 경우
(여기서 파악할 수 있는 수치값은 '키', '브랜드평판지수'이다.)
df.groupby('성별').mean()

#'혈액형'을 기준으로 묶어 '키'의 값에 대한 '평균'을 파악하려는 경우
df.groupby('혈액형')['키'].mean()

#'혈액형'을 1차 기준, 성별을 2차 기준으로 묶어 '키'의 값에 대한 '평균'을 파악하려는 경우
df.groupby([ '혈액형' , '성별' ])['키'].mean()

2-13. 중복값 제거하기
# dataframe에서 '혈액형'의 값만 추출한 경우

drop_duplicates(): category별 중복된 데이터 제거(= category별 최초 데이터만을 가져옴)
# dataframe의 '혈액형' 의 옵션 중 최초로 등장한 데이터만을 가져올 경우
(예: A형은 index 0번이 최초로, AB형은 index 3번이 최초로 출력됨)
df['혈액형'].drop_duplicates()
drop_duplicates의 소괄호 안에는 keep='first' 가 생략되어있다.
(아래에서 볼 수 있듯이 최초등장 data만 select한 것을 볼 수 있음.)

value_counts(): category별 갯수 파악.
# dataframe의 '혈액형' 내 category별 갯수를 파악하고 싶은 경우
df['혈액형'].value_counts()

NaN의 값은 생략하여 count됨.
아래의 데이터에서는 '강다니엘'이 빠져서 총 15개만 select됨. ('강다니엘'은 '그룹'이 NaN인 data)

2-14. 데이터프레임 병합
(예시 dataframe1: 아이돌의 정보 / dataframe2: 아이돌의 연봉, 가족 수)
df1 = pd.read_csv('http://bit.ly/ds-korean-idol')
df1

df2 = pd.read_csv('https://bit.ly/ds-korean-idol-2')
df2

우선적으로 Index의 재적용 필요
reset_index( drop=True ): index의 재적용.
drop=True 옵션을 사용하면 기존 index를 삭제할 수 있음.
pd.concat([df1,df2]): 복수 데이터의 병합.
sort=False옵션(=내림차순)으로 정렬. axis=0은 생략.
# df1과 df2를 병합
pd.concat([df1,df2],axis=1)

pd.merge(df1, df2, on=' ', how=' '): df1과 df2의 병합
( on='유니크한 값', how='병합의 기준'이며, how에 들어갈 병합의 기준은 left, right, inner가 있음)
# df1과 df2를 '이름'을 기준으로 df1에 병합하려 하는 경우
pd.merge(df1, df2, on='이름', how='left')

append({추가할 행의 데이터}, ignore_index=True ): DataFrame 객체에 새로운 행을 추가하는 메서드.
(ignore_index=True: 기존 DataFrame의 인덱스와 새로 추가된 행의 인덱스가 연속된 형태로 구성.)
# df2에 김사과라는 이름의 데이터를 새롭게 추가하며 해당 행의 인덱스를 연속된 형태로 구성하는 경우
df2 = df2.append({'이름':'김사과', '연봉':'5000', '가족수':'5'}, ignore_index=True)

columns=[변경할 필드값의 이름] : 필드값을 변경하고 싶은 경우
# df2의 필드값 '이름'을 '성함'으로 변경하고 싶은 경우
df2.columns = ['성함', '연봉', '가족수']
# 병합된 df1과 df2에서 중복되는 필드값인 '이름'을 구별하고 싶은 경우
(=오른쪽의 '이름'을 '성함'으로 변경하고 싶은 경우)
pd.merge(df1, df2, left_on='이름', right_on='성함', how='left')
( merge에서 'on'만을 그대로 적용하는 경우 → '이름' != '성함'이기 때문에 오류 발생)

2-15. 등수 매기기
rank(): dataframe, series의 순위를 매기는 함수. 기본값은 오름차순(ascending).
예제로 사용될 df1

# df1의 '브랜드평판지수'의 순위를 매겨 '브랜드순위'라는 새로운 필드값을 생성
df1['브랜드순위'] = df1['브랜드평판지수'].rank()
(rank는 오름차순이 기본이므로 맨 아래 순위가 1인 data의 브랜드평판지수가 제일 낮음.)

# df1의 '브랜드평판지수'가 가장 높은경우의 '브랜드순위'를 1로 매기고 싶은 경우
(=브랜드평판지수의 내림차순 정렬 시의 맨 위 값을 최고순위로 함)
df1['브랜드순위'] = df1['브랜드평판지수'].rank(ascending=False)

astype(): 자료형을 변경
# df1의 '브랜드순위'를 정수형으로 변경하려는 경우
df1['브랜드순위'] = df1['브랜드순위'].astype(int)

2-16. 날짜타입 사용하기
df.info()를 확인했을 때, 생년월일이 object 타입인 것을 확인할 수 있음.


to_datetime(): 날짜타입의 사용
# '생년월일' 필드를 object타입에서 datetime 타입으로 변환할 경우
df['생년월일'] = pd.to_datetime(df['생년월일'])

df['생년월일'].dt.year
# 연도만 가져오는 경우

df['생년월일'].dt.month
# 월만 가져오는 경우

df['생년월일'].dt.day
# 일만 가져오는 경우

df['생년월일'].dt.dayofweek
# 요일만 가져오는 경우 (0이 월요일 ~ 6이 일요일)

df['생년월일'].dt.isocalendar().week
# 몇번째 주 인지를 가져오는 경우

2-17. apply()
사용자가 정의한 함수를 DataFrame의 행 또는 열에 적용.
df.apply(func, axis=0)
func: 적용할 함수. 이 함수는 DataFrame의 각 행 또는 열에 적용.
axis: 함수가 적용될 방향을 지정합니다. 0일 경우 열마다, 1일 경우 행마다 함수가 적용.
broadcast, raw, reduce, result_type: 선택적인 매개변수로, 함수의 동작을 제어하는 추가적인 옵션.
args: 함수에 전달할 추가적인 인수들을 튜플 형태로 지정.
**kwds: 함수에 전달할 추가적인 키워드 인수들을 지정.
# 각 열의 합을 계산하기 위해 sum_column() 함수를 이용해 apply() 메서드에 적용하려는 경우
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
def sum_column(column):
return column.sum()
result = df.apply(sum_column, axis=0)
print(result)
적용을 위해서는 별도의 함수가 먼저 정의되어야 함.
→ 먼저 작성된 함수를 apply에 매개변수로 전달하는 과정을 거침.
# df1에서 '성별'이 남자는 1, 여자는 0으로 출력되도록 변경하고 싶은 경우
df1.loc[df1['성별']=='남자', '성별'] = 1
df1.loc[df1['성별']=='여자', '성별'] = 0
# df.loc[찾고자하는조건, 필드값]
df1.head()

2-18. map()
딕셔너리를 통해 data와 같은 key값을 적용.
df = pd.read_csv('http://bit.ly/ds-korean-idol')
df.head()

map_gender = {'남자':1, '여자':0}
df['성별'].map(map_gender)

df['New성별'] = df['성별'].map(map_gender)
df.head()

2-19. dataFrame의 산술연산
df = pd.DataFrame({
'파이썬': [60, 70, 80, 86, 95],
"데이터분석": [40, 60, 70, 55, 88],
"머신러닝딥러닝": [90, 40, 30, 100, 55]
})
df

type(df['파이썬'])
df['파이썬']+df['데이터분석']+df['머신러닝딥러닝']

df['총점']=df['파이썬']+df['데이터분석']+df['머신러닝딥러닝']
df

df['평균']=df['총점']/3
df

# 파이썬의 총 점수를 합계하고 싶은 경우
df['파이썬'].sum() # df['파이썬'].sum(axis=0)

df1 = pd.DataFrame({
'파이썬': [60, 70, 80, 86, 95],
"데이터분석": [40, 60, 70, 55, 88],
"머신러닝딥러닝": [90, 40, 30, 100, 55]
})
df2 = pd.DataFrame({
'파이썬': ['C', 'A', 'B', 'C', 'B'],
"데이터분석": [40, 60, 70, 55, 88],
"머신러닝딥러닝": [90, 40, 30, 100, 55]
})
# 이 상황에서 df1 + df2는 에러가 발생함.
df1 = pd.DataFrame({
"데이터분석": [40, 60, 70, 55, 88],
"머신러닝딥러닝": [90, 40, 30, 100, 55]
})
df2 = pd.DataFrame({
"데이터분석": [40, 60, 70, 55],
"머신러닝딥러닝": [90, 40, 30, 100]
})
# df1은 5개, df2는 4개이므로 더할 시 빠진 데이터쪽에 NaN이 발생.
df1+df2

2-20. select_dtypes
#df 복원
df = pd.read_csv('ht1tp://bit.ly/ds-korean-idol')
df.info()

#문자열 컬럼만 빼고 가져오기
df.select_dtypes(exclude='object')

#문자가 아닌 컬럼에만 10을 더함
df.select_dtypes(exclude='object')+10

# 문자열을 가진 컬럼만 저장
str_cols = df.select_dtypes(include='object').columns
str_cols

df[str_cols]

2-21. One Hot Encoding
범주형 변수를 머신러닝 알고리즘에 적용하기 위해 사용되는 기법 중 하나.
특히, pandas라이브러리에서는 범주형 변수를 One Hot Encoding하기 위한 편리한 기능을 제공함.
One Hot Encoding은 주어진 범주형 변수의 각 값에 대해 새로운 이진 열을 생성함.
이 이진 열은 해당 값이 존재하는 경우 1을 가지고, 그렇지 않은 경우 0을 가짐.
이를 통해 범주형 변수를 숫자형 변수로 변환하고, 알고리즘이 범주형 데이터를 이해하고 처리할 수 있음.
pandas에서는 pd.get_dummies() 함수를 사용하여 원핫인코딩을 수행할 수 있음.
이 함수는 DataFrame의 범주형 변수를 선택하고, 해당 변수를 원핫인코딩된 열로 변환하여
새로운 DataFrame을 반환함.
# df['혈액형_code']를 머신러닝/딥러닝 알고리즘에 넣어 데이터를 예측하려 하는 경우
지시를 내릴 시, 컴퓨터는 값들 간의 관계를 스스로 형성하게 됨.
→ 만약 B형은 1, AB형은 2라는 값을 갖고 있을 때 컴퓨터는 'B형+AB형=O형'이라는 이상한 관계가 됨.
→ 별도의 column들을 형성해주고 1개의 column에는 1, 나머지는 0을 넣어줌으로
'A, B, AB, O'는 '서로 독립적인 관계이다'라는 카테고리로 표현해주는 방식을 사용함.
blood_map = {'A':0, 'B':1, 'AB':2, 'O':3}
df.head()

df['혈액형_code']=df['혈액형'].map(blood_map)
df.head()

# pd.get_dummies(): 원 핫 인코딩을 적용하는 함수.
pd.get_dummies(df['혈액형_code'])

df = pd.get_dummies(df, columns=['혈액형_code'])
df

df.info()
