본문 바로가기

Python/데이터 분석(전처리, 시각화)

파이썬(6)-Pandas(2)

*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*

8. 통계함수

df.describe()

df['height'].sum() # 합계
df['height'].count() # 갯수, NaN은 미포함
df['height'].mean() # 평균
df['height'].median() #중위값
df['height'].max() #최댓값
df['height'].min() #최솟값
df['height'].var() # 분산: 확률분포에서 데이터가 퍼져있는 정도
# 데이터가 평균으로부터 얼마만큼 퍼져있는지
# (데이터-평균)**2을 모두 다 더한 값 / 데이터의 갯수
# 표준편차: 분산에 루트씌운
df['height'].std()


9. 그룹화

groupby(): 데이터를 그룹으로 묶습니다.

# groupby(): 데이터를 그룹으로 묶어 분석할 때 사용
df.groupby('group')

df.groupby('group').count()

df.groupby('group').mean(numeric_only=True)

df.groupby('group').mean(['height','brand'])

df.groupby('gender').mean(numeric_only=True)

문제 1
혈액형별로 그룹을 맺어, 키의 평균값을 확인

df.groupby('blood')['height'].mean()

문제 2
혈액형별로 그룹을 맺고, 성별로 또 그룹을 나눈 후 키의 평균값을 확인

df.groupby(['blood', 'gender'])['height'].mean()


10. 중복값 제거하기

df['blood']

drop_duplicates(): 중복된 데이터를 제거합니다.

# drop_duplicates(): 중복된 데이터를 제거
df['blood'].drop_duplicates()

# keep='last' 옵션, 마지막 index기준 중복값 제거
df['blood'].drop_duplicates(keep='last')

value_counts(): 해당 column에 대한 데이터의 갯수 반환

# value_counts(): 열의 각 값에 대한 데이터의 갯수를 반환, NaN은 생략
# 특히 데이터분석할 때 많이 사용함.
df['blood'].value_counts()

df['company'].value_counts()

# NaN도 보고싶어, NaN 표기
df['company'].value_counts(dropna=False)


11. 데이터프레임 합치기

df1 = pd.read_csv('/content/drive/MyDrive/KDT/5. 데이터 분석/데이터/idol.csv')
df2 = pd.read_csv('/content/drive/MyDrive/KDT/5. 데이터 분석/데이터/idol2.csv')

concat([df1, df2]): df1과 df2을 합칩니다.

df_copy = df1.copy()
df_concat = pd.concat([df1, df_copy]) #axis=0 (기본값) -> 축:행

# reset_index(): index를 새롭게 적용
# 기존 index가 살아있다는 문제
# drop=True 옵션을 사용하여 기존 index가 컬럼으로 만들어지는 것을 방지
df_concat.reset_index(drop=True)

# 열 합치기
# 같은 index끼리 결합
pd.concat([df1, df2], axis=1)

drop(): 행(row) 또는 열(column) 삭제

# 1,3,5,7행 삭제
df3 = df2.drop([1,3,5,7])
df3

# 없는 column은 NaN처리
pd.concat([df1, df3], axis=1)

df_right = df2.drop([1,3,5,7,9],axis=0)
df_right

df_right = df_right.reset_index(drop=True)
df_right

merge(): 두 데이터프레임 합치기

# merge(): 특정 고유한 키(unique, id)값을 기준으로 합침
# merge(데이터프레임1, 데이터프레임2, on='유니크값, how='병합의 기준')
# 병합의 기준: left, right, inner, cross
# SQL에서 JOIN과 비슷함
pd.merge(df1, df_right, on='이름', how='left')

pd.merge(df1, df_right, on='이름', how='right')

pd.merge(df1, df_right, on='이름', how='inner')

# cross는 모든 경우의수로 다 합쳐봄
pd.merge(df1, df_right, how='cross')

문제
df_right 데이터프레임에 아래와 같은 데이터를 추가하고 df1과 merge하여 출력
"이름: 김사과, 연봉: 7000, 가족수: 10"
단, how=right로 설정

df_apple = pd.DataFrame({'이름':['김사과'], '연봉':[7000], '가족수': [10]})
df_right = pd.concat([df_right, df_apple],ignore_index=True)
pd.merge(df1, df_right, on='이름', how='right')

# 칼럼 이름 -> 성함으로 바뀐다?
df_right.columns=['성함', '연봉', '가족수']
df_right

# pd.merge(df1, df_right, on='이름', how='right') # KeyError: '이름'
pd.merge(df1, df_right, left_on='이름', right_on='성함', how='right') #칼럼을 이름, 성함 둘 다 사용하기


12. 등수 매기기

# rank(): 데이터프레임 또는 시리즈의 순위를 매기는 함수. 기본값은 ascending
# 파생변수: 기존 행을 사용하여 새로운 열 만들기
df1['브랜드순위'] = df1['브랜드평판지수'].rank()
df1

# 랭크 내림차순
df1['브랜드순위'] = df1['브랜드평판지수'].rank(ascending=False)
df1

# astype(): 특정열의 자료형을 변경
df1['브랜드순위'] = df1['브랜드순위'].astype(int)
df1

df1['브랜드순위'].dtypes


13. 날짜타입 사용하기

df.info()

df['birthday']

to_datetime(): object -> datetime type 변환

# to_datetime(): object타입에서 datetime타입으로 변환
df['birthday'] = pd.to_datetime(df['birthday'])
df['birthday']

# dt속성에서 year속성
df['birthday'].dt.year
# dt속성에서 month속성
df['birthday'].dt.month
# 날짜
df['birthday'].dt.day
# 분
df['birthday'].dt.minute
# 초
df['birthday'].dt.second

# 1주일중 몇번째 날짜
df['birthday'].dt.dayofweek

# 1년중에 몇번째 week인지 뽑아줌, 외국에서 많이 사용
df['birthday'].dt.isocalendar().week


14. apply 사용하기

ML, DL할 때 많이 활용: 기계는 문자를 학습하지 못하기에, 숫자로 넣어줘야하기 때문(전처리 가공)
데이터 전처리: 사용하고 싶은 데이터만 수렴해서 축소화
Series나 DataFrame에 구체적인 로직을 적용하고 싶을 때 사용합니다.
apply를 적용하기 위해서는 별도의 함수를 먼저 정의해야 합니다.
작성된 함수를 apply에 매개변수로 전달합니다. (js의 eventlistner?)

# 성별이 남자는 1, 여자는 0으로 변환(loc이용)
df.loc[df['성별'] == '남자', '성별'] = 1
df.loc[df['성별'] == '여자', '성별'] = 0
df = pd.read_csv('/content/drive/MyDrive/KDT/5. 데이터 분석/데이터/idol.csv')
def male_or_femail(x):
    if x == '남자':
        return 1
    elif x == '여자':
        return 0
    else:
        return None
        
df['성별'].apply(lambda x: 1 if x == '남자' else 0)

df['New성별'] = df['성별'].apply(lambda x: 1 if x == '남자' else 0)
df.head()


15. map 사용하기

딕셔너리를 통해 데이터와 같은 키의 값을 적용합니다.

map() 함수는 Pandas에서 Series 객체에 대해 각 요소를 변환하는 데 사용되는 함수입니다. apply() 함수와 유사하지만, 주로 단일 열 또는 Series 객체에 적용됩니다.

df = pd.read_csv('/content/drive/MyDrive/KDT/5. 데이터 분석/데이터/idol.csv')
map_gender = {'남자':1, '여자':0}
df['성별'].map(map_gender)

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


16. 데이터프레임의 산술연산

df = pd.DataFrame({
    '파이썬': [60,70,80,86,95],
    '데이터분석': [40,60,70,55,87],
    '머신러닝딥러닝': [35,40,30,80,55]
})

df

df1 = pd.DataFrame({
    '데이터분석': [40, 60, 70, 80, 35],
    '머신러닝딥러닝': [75, 65, 87, 80, 85]
})
df2 = pd.DataFrame({
    '데이터분석': [40, 60, 70, 80, 35],
    '머신러닝딥러닝': [75, 65, 87, 80, 85]
})

# 행의 갯수가 다를 경우 빠진 데이터를 NaN으로 취급하기 때문에 연산이 안됨
df1 + df2


17. select_dtypes

select_dtypes() 함수는 Pandas 라이브러리에서 데이터프레임의 특정 데이터 타입을 가진 열만 선택하는 데 사용됩니다. 이 함수는 데이터 타입을 기준으로 열을 필터링하여 새로운 데이터프레임을 반환합니다.

df = pd.read_csv('/content/drive/MyDrive/KDT/5. 데이터 분석/데이터/idol.csv')
df.info()

# 문자열 column만 가져오기
df.select_dtypes(include='object')

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

# 문자가 아닌 column에만 10을 더함(NaN값은 계산불가)
df.select_dtypes(exclude='object')+10

문제
문자열을 가지고 있는 column의 이름만 저장하여 출력

str_cols = df.select_dtypes(include='object').columns
str_cols

df[str_cols]


18. 원 핫 인코딩(One Hot Encoding)

원 핫 인코딩은 한개의 요소는 1, 나머지 요소는 0으로 만들어 카테고리형을 표현하는 방법 = 범주형 데이터를 이진 벡터로 변환하는 기법입니다.
문자를 숫자로 바꿔주기: 일반적인 숫자와 구분하기 위해, 카테고리 숫자를 써주기
ML에서 필수적인 전처리 과정
다른말론 Label Encoding
예) df['혈액형']

  • 머신러닝/딥러닝 알고리즘에 넣어 데이터를 예측하려고 한다면 라벨 인코딩을 하여 수치 데이터로 변환
  • 컴퓨터는 값들간의 관계를 스스로 형성하게 될 수 있다.
  • 만약 B형은 1, AB형이 2라는 값을 가지고 있다면 컴퓨터는 'B형 + AB형 = O형'라는 이상한 관계를 맺을 수 있음
  • 별도의 column들을 형성해주고 1개의 column에는 1, 나머지 column에는 0으로 넣어줌으로 'A, B, AB, O'형의 관계는 서로 독립적이다'라는 카테고리로 표현하는 방식(원 핫 인코딩) - Boolean타입 True/False처럼 1과 0인 것 이분법적으로 나눠서 관계성을 표현.
blood_map = {'A':0, "B":1, "AB":2, "O":3}
df['혈액형_code'] = df['혈액형'].map(blood_map) # 라벨인코딩: 문자->숫자 변환 작업
df.head()

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

df= pd.get_dummies(df, columns=['혈액형_code']) # column 늘어남
df

df.info() # 원 핫 인코딩으로 생긴 자료들은 boolean type이다.