본문 바로가기
인공지능/데이터분석

판다스-기초1

by hyunji00pj 2025. 1. 16.

1. 판다스(Pandas)

판다스(Pandas)는 데이터 분석을 위한 파이썬 라이브러리 중 하나로, 표 형태의 데이터나 다양한 형태의 데이터를 쉽게 처리하고 분석할 수 있도록 도와주는 도구입니다. 주로 데이터프레임(DataFrame)이라는 자료구조를 제공하며, 이를 통해 테이블 형태의 데이터를 다루기 용이합니다.

pip install pandas
import pandas as pd # 거의 공식 처럼 pd라고 이름을 줌

2. Series와 DataFrame

 

2-1. Series

Series는 1차원 배열과 같은 자료구조로 하나의 열을 나타냅니다. 또한 각 요소는 인덱스(index)와 값(value)으로 구성되어 있습니다. 값은 넘파이의 ndarray 기반으로 저장됩니다. Series는 다양한 데이터 타입을 가질 수 있으며 정수, 실수, 문자열 등 다양한 형태의 데이터를 담을 수 있습니다. (여러개가 하나에 들어간다는 뜻은 아님! ex) [int,str,float] (X))

idx = ['김사과', '반하나', '오렌지', '이메론', '배애리']
data = [67, 75, 90, 62, 98]

# pd.Series(데이터, 인덱스, ...(그 외에 쓸 옵션))

pd.Series(data)
# 열 이름은 0번으로 주어짐 데이터에 값이 5개가 있으니까 인덱스 5개 자동으로 주어짐

pd.Series(data, idx)

se1 = pd.Series(data, idx)
se1
print(se1.index)
print(type(se1.index))

# 출력
# Index(['김사과', '반하나', '오렌지', '이메론', '배애리'], dtype='object')
# <class 'pandas.core.indexes.base.Index'>
print(se1.values)
print(type(se1.values))

# 출력
# [67 75 90 62 98]
# <class 'numpy.ndarray'>

2-2. DataFrame

데이터프레임(DataFrame)은 판다스(Pandas) 라이브러리에서 제공하는 중요하고 강력한 데이터 구조로, 2차원의 테이블 형태 데이터를 다루는 데 사용됩니다. 또한 각 요소는 인덱스(index), 열(column), 값(value)으로 구성되어 있습니다. 데이터프레임은 행과 열로 이루어져 있으며, 각 열은 다양한 데이터 타입을 가질 수 있습니다. 값은 넘파이의 ndarray 기반으로 저장됩니다.

data = [[67, 93, 91],
        [75, 68, 96],
        [87, 81, 82],
        [62, 70, 75],
        [98, 56, 87]]

idx = ['김사과', '반하나', '오렌지', '이메론', '배애리']
col = ['국어', '영어', '수학']
# pd.DataFrame(데이터, 인덱스, 컬럼, ...(option))
pd.DataFrame(data)

pd.DataFrame(data, idx)

pd.DataFrame(data, idx, col)

df = pd.DataFrame(index=idx, columns=col, data=data) #변수 이름 명시해주면 순서 바뀌어서 넣어줘도 상관 없음
df

print(df.index)
print(df.columns)
print(df.values)

# 출력
# Index(['김사과', '반하나', '오렌지', '이메론', '배애리'], dtype='object')
# Index(['국어', '영어', '수학'], dtype='object')
# [[67 93 91]
#  [75 68 96]
#  [87 81 82]
#  [62 70 75]
#  [98 56 87]]
# 딕셔너리를 사용하여 데이터프레임을 생성하기
dic = {
    '국어':[67, 75, 76, 62, 98],
    '영어':[93, 68, 81, 70, 56],
    '수학':[91, 96, 82, 75, 87]
}

df = pd.DataFrame(data=dic, index=idx)
df

3. CSV 파일 읽어오기

CSV 파일은 Comma-Separated Values(쉼표로 구분된 값) 파일의 약자로, 데이터를 단순한 텍스트 형식으로 저장하는 데 사용되는 파일 형식입니다.

 

  • 위 링크에서 파일을 다운받고 구글드라이브에 업로드합니다.
    • (수업중 경로는 10.데이터 분석 안에 Data 폴더 만든 후에 위 링크 파일 집어 넣었음)
  • 구글 드라이브 마운트 해서 파일의 경로 복사함

idol (1).csv
0.00MB

df = pd.read_csv('내드라이브경로/idol (1).csv')
df

type(df)

4. 데이터프레임 기본 정보 알아보기

# info(): 행(row), 열(column)의 기본적인 정보와 데이터 타입을 반환
df.info()

위 코드를 결과를 캡쳐해서 컴퓨터 마우스로 메모한거라 좀 삐뚤빼뚤한점 양해부탁드립니다...

df.columns

# 출력
# Index(['이름', '그룹', '소속사', '성별', '생년월일', '키', '혈액형', '브랜드평판지수'], dtype='object')
# 컬럼명 변경하기
new_columns = ['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand']
df.columns = new_columns # 갯수 맞아야함!
df

# describe(): 통계 정보를 반환
df.describe()
# 기본값으로 통계 정보가 수치정보로 된 정보만 나와서 수치로 된 키와 평판지수만 나온 것

# count : 데이터 개수
# mean : 평균 값
# std 표준편차 : 평균으로부터 얼마만큼 떨어져있는지의 척도
# min : 최소값
# max : 최대값

df.describe(include=object)
# 문자열에 대한 통계정보
# unique : 얼마만큼 서로 데이터가 다른지를 나타냄 (종류)
# top : 최빈값을 나타냄 name과birth는 가장 많은 종류가 없기에 맨 위에것 뽑은것
# freq : 최빈값의 갯수 (ex:방탕소년단 5개 빅히트 7개 여자13개 있다는 것)

# 원하는 개수의 데이터 보기
# 상위 3개의 row를 출력
df.head(3)

df.tail(5) # 하위 5개의 row를 출력

# 정렬하기
df.sort_index() # index로 오름차순 정렬: 기본값

df.sort_index(ascending=False) # index로 내림차순 정렬

df.sort_values(by='height') # 키로 오름차순 정렬

df.sort_values(by='height', ascending=False) # 키로 내림차순 정렬

df.sort_values(by='height', ascending=False, na_position='first') # 키로 내림차순 정렬. NaN을 위로 올림

# 1차 정렬: 키(내림차순), 2차 정렬: 브랜드(내림차순)
df.sort_values(by=['height', 'brand'], ascending=[False, False],na_position='first')

5. 데이터 다루기

df.head()

df['blood']

type(df['blood']) #series

df.blood #.으로 접근해서 뽑기 가능, 데이터프레임의 객체로 접근

df[:3]#슬라이싱으로 가져올 수 있음

# loc 인덱싱: 컬럼 인덱싱
df.loc[:, 'name'] # df['name']
# , 를 기준으로 앞엔 행에 대한 조건 뒤에는 열에 대한 조건이 들어감

df.loc[2:5, 'name'] # 슬라이싱 조건을 추가할 수 있음
# 다른 슬라이싱과 달리 5전까지가 아니라 5를 포함해서 가져옴

df.loc[2:5, ['name', 'gender', 'height']]

df.loc[[2,5], ['name', 'gender', 'height']]
#하나씩 가져오기

df.loc[[2,5], 'name':'gender']

# iloc 인덱싱: index로 인덱싱하는 방법 (말 그대로 인덱스이기 때문에 끝에 번호를 포함하지 않음)
df.iloc[:, 0]

df.iloc[:, 0:3]
# 인덱스 이기때문에 3번은 포함하지 않고 0,1,2까지 가져옴

df.iloc[:, [0,3]]

df.iloc[1:5, 0:2]
#1부터 5되기 전까지 0부터 2되기 전까지 가져옴

df['height'] >= 180 # bool값으로 반환해줌

df[df['height'] >= 180]

여러가지 조건을 추가해서 데이터 뽑기

df[df['height'] >= 180]['name']

df['name'][df['height'] >= 180] # == df[df['height'] >= 180]['name']
df[df['height'] >= 180][['name', 'gender', 'height']]

#loc로 바꾸기 파이썬 개발자들은 loc많이 씀 가독성이 더 좋아서 권장함
df.loc[df['height'] >= 180,['name', 'gender', 'height']]
company = ['빅히트', '어도어']
df['company'].isin(company) #isin: 데이터가 포함되어 있는지 확인해 True,false로 반환해 주는 메소드

df[df['company'].isin(company)] # df.loc[df['company'].isin(company),:]

df.loc[df['company'].isin(company),:]

확실히 이편이 가독성이 훨씬 좋다

6. 결측값

결측값은 값이 누락된 데이터를 의미하며, 판다스에서는 일반적으로 NaN(Not a Number) 또는 None으로 표시됩니다.

  1. NaN : 수치 데이터에서 나타나는 결측값으로, 판다스의 float 타입에서 주로 사용됩니다.
  2. None : 비수치 데이터에서 나타나는 결측값으로, object 데이터 타입에서 사용됩니다.
df # 강다니엘 태연 다니엘에 NAN값이 있음

 

# 상황에 따라서 최빈값을 넣던 0을 넣던 결측지를 어떻게 처리할지 생각해야함
# 그치만 웬만하면 결측치를 삭제하거나 결측치가 없는거로 데이터를 모으는게 좋음
df.isna() # t,f로 반환해줌 NaN값을 t 아닌 값은 f로 반환
df.isnull() #마찬가지로 t,f로 반환해줌
df.notnull()# 반대 메소드 NaN값을 f 아닌 값은 t

df[df['height'].isna()]# height 가 NaN인사람 뽑기

df[df['height'].isna()]['name']#이름만 뽑기

df[df['height'].notnull()]#키 notnull인 사람만 뽑기
df[~df['height'].isnull()]#반대값 줄때 ~써서도 가능

df.loc[df['company'].notnull(), ['name', 'company', 'group', 'gender']]#loc이용해서 company가 notnull인 사람의 이름과 company,group,gender뽑기

# fillna(): 결측값을 채워주는 함수
#9번 결측치를 0으로 채우기
df['height'].fillna(0) # 저장 아직 안함 실제 데이터는 안변함
 # df['height'].fillna(0, inplace=True) -> 데이터 변경 적용할 수 있게 됨

df_copy = df.copy()
df_copy
#키 평균값 채우기 위해 평균값 구함
height = df_copy['height'].mean()
height

# 출력
# 170.53684210526316
# NaN에 키 평균값으로 채우기
df_copy['height'] = df_copy['height'].fillna(height)
df_copy['height']

 

NaN값에 함부로 값을 채우는건 데이터 전처리로써 좋은 선택은 아니지만 판다스를 배우는 과정이기에 사용해 보았다

#이번에는 중위값으로 채우기위해 중위값 구하기(실제 있는 값 중에 가운데 값임을 의미)
height = df_copy['height'].median() # 50%값, 중위
height

# 출력
# 168.0
# NaN값에 중위값으로 채우기 적용
df_copy['height'].fillna(height, inplace=True)
df_copy['height']

# dropna(): 결측값이 있는 행 또는 열을 제거. 결측값이 한개라도 있는 경우 삭제
# 기본값 : axis=0 (행 삭제 생략)
df_copy.dropna()

df_copy.dropna(axis=1) # 결측값이 있는 열을 제거 (거의 안씀 중요한 항목들을 다 날리기 때문)

※ axis

  1. NumPy는 수학적 배열 연산에서 출발했기 때문에, 축(axis) 개념이 배열의 모양과 연산 방향에 초점을 맞춥니다.
    • axis=0: 배열의 세로 방향(열), axis=1: 배열의 가로 방향(행)
  2. Pandas는 데이터 분석에 특화된 라이브러리로, 행(row) 열(column)을 명시적으로 구분하여 작업을 수행합니다.
    • axis=0: 행(row)을 대상으로 작업(열 간 연산). axis=1: 열(column)을 대상으로 작업(행 간 연산)

7. 행, 열 추가 및 삭제하기

 

dic = {
    'name': '김사과',
    'group': '과수원',
    'company': '애플',
    'gender': '여자',
    'birthday': '2000-01-01',
    'height': 160.0,
    'blood': 'A',
    'brand': 1234567
}

 

# concat(): 데이터를 합침, axis=0 (기본값 행으로 합침)
# pd.concat([첫번째 데이터 프레임, 두번째 데이터 프레임])
# index=[0] 딕셔너리라 인덱스가 없기 때문에 인덱스 추가
# 추가했기때문에 인덱스 충돌이 남
# ignore_index=True 인덱스를 합치면서 충돌나는 녀석을 자연스럽게 재정의 하게 함 이거 안하면 에러남
df_copy = pd.concat([df_copy, pd.DataFrame(dic, index=[0])], ignore_index=True)
df_copy

맨 아래에 dic가 추가되었다

df_copy['nation'] = '한국' # 새로운 컬럼 추가
df_copy.head()

df_copy.loc[df_copy['name']=='김사과','nation']='미국'
df_copy.tail()

김사과만 nation값을 미국으로 바꾸기

df_copy.drop([1,3,5,7,20],axis=0)

해당 인덱스 행만 제거

df_copy.drop(['nation','group'],axis=1)

'nation','group'열만 제거

8. 통계 함수

df_copy.describe()
df_copy['height'].sum() #합계
# 3400.2

df_copy['height'].count() #개수,NaN을 포함하지 않음
# 20

df_copy['height'].mean() #평균
# 170.01

df_copy['height'].median() # 중앙값
# 168.0

 

평균은 모든 데이터를 더한 후, 데이터 개수로 나눈 값입니다. 데이터를 고르게 분배했을 때, 한 데이터가 가질 수 있는 이론적인 중심값을 의미합니다. 중앙값은 데이터를 크기 순서대로 정렬했을 때, 가운데 위치하는 값입니다. 데이터의 순서에만 영향을 받고, 값의 크기에는 영향을 받지 않습니다. 데이터가 고르게 분포된 경우 평균과 중앙값이 비슷하거나 같습니다. 하지만 데이터에 극단값(Outlier)이 있는 경우 평균은 극단값의 영향을 받아 왜곡될 수 있지만, 중앙값은 비교적 안정적입니다.

df_copy['height'].max() # 최대값
# 182.0

df_copy['height'].min() # 최소값
# 160.0

df_copy['height'].var() # 분산
# 55.007263157894734

df_copy['height'].std() # 표준 편차
# 7.416688152935563

분산(Variance) 표준편차(Standard Deviation)는 데이터가 평균에서 얼마나 퍼져 있는지를 나타내는 산포도(분포 정도)를 측정하는 지표입니다. 분산은 데이터가 평균을 기준으로 얼마나 퍼져 있는지를 나타냅니다. 평균에서 각 데이터의 거리를 제곱한 값들의 평균입니다. 표준편차는 분산의 제곱근입니다. 분산은 제곱 값이기 때문에 단위가 커질 수 있는데, 이를 원래 데이터와 같은 단위로 변환하기 위해 제곱근을 씌웁니다.

 

9. 그룹

# groupby(): 데이터를 그룹으로 묶어 분석할 때 사용
df_copy.groupby('group')
# 그룹을 맺으면 통계함수를 사용할 수 있음
df_copy.groupby('group').count()

df_copy.groupby('group').mean(numeric_only=True) 
#numeric_only 를 써줘야 숫자로 된값만 통계 내줌 안쓰면 숫자가 아닌거 통계 어떻게 내냐고 에러뜸

df_copy.groupby('group').sum(numeric_only=True) #합계
df_copy.groupby('group').mean(numeric_only=True) # 평균
df_copy.groupby(['blood','gender']).mean(numeric_only=True)
# 여러 그룹으로 평균

df_copy.groupby(['blood','gender'])['height'].mean() 
#하나만 보고싶으면 .mean()앞에 조건을 붙여서 하나만 뽑은 후에 평균 내면 됨

10. 중복값 제거하기

df_copy['blood']

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

df_copy['blood'].drop_duplicates(keep='last')

# 진짜 너무너무 많이 씀 꼭 공부하자!
# value_counts(): 열의 각 값에 대한 데이터의 개수를 반환. NaN은 생략
df_copy['blood'].value_counts()

df_copy['company'].value_counts()

df_copy['company'].value_counts(dropna=False) #NaN값을 포함하고 싶다면 이렇게!

'인공지능 > 데이터분석' 카테고리의 다른 글

Matplotlib  (1) 2025.01.17
판다스-기초2(데이터프레임 합치기,원-핫 인코딩)  (0) 2025.01.17
넘파이 - 기초  (0) 2025.01.16
텐서(Tensor)  (0) 2025.01.07
파이토치 프레임워크  (0) 2025.01.06