인공지능/LLM 서비스 개발

판다스

mino28 2025. 7. 17. 16:03

1. 판다스(Pandas)

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

pip install pandas

 

import pandas as pd

 

 

2. Series와 DataFrame

1. Series

Series 1차원 배열과 같은 자료구조로 하나의 열을 나타냅니다. 또한  요소는 인덱스(index) (value)으로 구성되어 있습니다. 값은 넘파이의 ndarray 기반으로 저장됩니다. Series 다양한 데이터 타입을 가질  있으며 정수, 실수, 문자열  다양한 형태의 데이터를 담을  있습니다

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

# pd.Series(데이터, 인덱스, ...)
pd.Series(data)

 

se1 = pd.Series(data, idx)
se1

 

print(se1.index)
print(se1.values)
print(type(se1.values))

 

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(데이터, 인덱스, 컬럼, ...)
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)

 

# 딕셔너리를 사용하여 데이터프레임을 생성하기
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(쉼표로 구분된 값) 파일의 약자로, 데이터를 단순한 텍스트 형식으로 저장하는 데 사용되는 파일 형식입니다.

 

아래 파일을 다운받고 구글드라이브에 업로드합니다.

 

 

 

df = pd.read_csv('/본인 구글드라이브 경로/idol.csv')
df

 

type(df)

 

 

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

df.info()

 

df.columns

 

new_columns = ['name', 'group', 'company', 'gender', 'birthday', 'height', 'blood', 'brand']
df.columns = new_columns
df

 

# describe(): 통계 정보를 반환
df.describe()

 

df.describe(include=object) # Top: 최빈값, freq: 최빈값의 빈도

 

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

 

df.head(3) # 상위 3개의 row를 출력

 

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

 

df.tail(2) # 하위 2개의 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'])

 

df.blood

 

df.head(3)

 

df[:3]

 

# loc 인덱싱: 컬럼 인덱싱
df.loc[:, 'name'] # df['name']

 

df.loc[2:5, 'name'] # 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을 포함하지 않음

 

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

 

df.iloc[1:5, 0:2]

 

df['height'] >= 180

 

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

 

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

 

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

 

df.loc[df['height'] >= 180, ['name', 'gender', 'height']]

 

df

 

company = ['빅히트', '어도어']
df['company'].isin(company)

 

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

 

 

6. 결측값

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

df.info()

 

df

 

df.isna()

 

df.isnull()

 

df.notnull()

 

df['height'].isna()

 

df[df['height'].isna()]

 

df[df['height'].isna()]['name']

 

df[df['height'].notnull()]

 

df[~df['height'].isnull()]

 

df.loc[df['company'].notnull(), ['name', 'company', 'group', 'gender']]

 

df['height']

 

# fillna(): 결측값을 채워주는 함수
df['height'].fillna(0) # df['height].fillna(0, inplace=True) 적용

 

df['height']

 

df_copy = df.copy()
df_copy

 

height = df_copy['height'].mean()
height

 

df_copy['height'] = df_copy['height'].fillna(height)
df_copy['height']

 

df_copy = df.copy()
df_copy['height']

 

height = df_copy['height'].median() # 50%값, 중위
height

 

df_copy['height'].fillna(height, inplace=True)
df_copy['height']

 

df_copy = df.copy()
df_copy

 

# 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. 행, 열 추가 및 삭제하기

df_copy = df.copy()
df_copy

 

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

 

# concat(): 데이터를 합침. axis=0 (기본값)
df_copy = pd.concat([df_copy, pd.DataFrame(dic, index=[0])], ignore_index=True)
df_copy

 

df_copy['nation'] = '대한민국'
df_copy.head()

 

df_copy.tail()

 

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

 

# 행 제거하기
df_copy.drop(20, axis=0) # 0: 행, 1: 열

 

df_copy.tail()

 

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

 

# 열 제거하기
df_copy.drop('nation', axis=1)

 

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

 

 

8. 통계 함수

df_copy.describe()

 

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

 

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

 

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

 

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

 

※ 평균과 중앙값

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

 

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

 

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

 

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

 

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

 

※ 분산과 표준편차

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

 

 

 

 

 

9. 그룹

df_copy

 

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

 

# 그룹을 맺으면 통계함수를 사용할 수 있음
df_copy.groupby('group').count()

 

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

 

df_copy.groupby('group').sum(numeric_only=True)

 

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

 

df_copy.groupby(['blood','gender']).mean(numeric_only=True)

 

df_copy.groupby(['blood','gender'])['height'].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를 포함

 

 

11. 데이터프레임 합치기

 

아래 파일을 다운받고 추가로 구글드라이브에 업로드합니다.

 

 

df1 = pd.read_csv('/본인 구글드라이브 경로/idol.csv')
df2 = pd.read_csv('/본인 구글드라이브 경로/idol2.csv')

 

df1

 

df2

 

df_copy = df1.copy()

 

pd.concat([df1, df_copy]) # axis=0 (기본값)

 

df_concat = pd.concat([df1, df_copy])

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

 

pd.concat([df1, df2], axis=1) # 같은 index와 결합

 

df3 = df2.drop([1, 3, 5, 7, 9])
df3

 

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

 

dic = {
    '이름': '김사과',
    '연봉': 9000,
    '가족수': 10
}

 

df_right = pd.concat([df_right, pd.DataFrame(dic, index=[0])], ignore_index=True)
df_right

 

pd.concat([df1, df_right], axis=1)

 

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

 

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

 

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

 

pd.merge(df1, df_right, how='cross')

 

df_right.columns = ['성함', '연봉', '가족수']
df_right

 

# pd.merge(df1, df_right, on='이름', how='inner') KeyError: '이름'
pd.merge(df1, df_right, left_on='이름', right_on='성함', how='inner')

 

 

12. 등수 매기기

# rank(): 데이터프레임 또는 시리즈의 순위를 매기는 함수. 기본값은 ascending
df1['브랜드순위'] = df1['브랜드평판지수'].rank()
df1

 

df1['브랜드순위'] = df1['브랜드평판지수'].rank(ascending=False)
df1

 

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

 

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

 

 

13. 날짜타입 사용하기

df_copy = df.copy()
df_copy

 

df_copy.info()

 

df_copy.info()['birthday']

 

# to_datatime(): object타입에서 datetime타입으로 변환
df_copy['birthday'] = pd.to_datetime(df_copy['birthday'])
print(type(df_copy['birthday']))
print(df_copy['birthday'].dtypes)

 

df_copy.info()

 

df_copy['birthday'].dt.year

 

df_copy['birthday'].dt.month

 

df_copy['birthday'].dt.day

 

df_copy['birthday'].dt.hour

 

df_copy['birthday'].dt.minute

 

df_copy['birthday'].dt.second

 

df_copy['birthday'].dt.dayofweek # 요일: 0(월요일) ~ 6(일요일)

 

df_copy['birthday'].dt.isocalendar().week

 

 

14. apply 사용하기

Pandas의 apply() 함수는 데이터프레임이나 시리즈의 데이터를 사용자 정의 함수 또는 내장 함수에 적용하여 새로운 값을 계산하거나 변환할 때 사용됩니다. 데이터를 행(row) 또는 열(column) 단위로 처리할 수 있는 강력한 도구입니다.

df_copy = df.copy()
df_copy
df_copy.head()

 

# 성별을 남자는 1, 여자는 0으로 변환(loc를 사용)
df_copy.loc[df_copy['gender'] == '남자', 'gender'] = 1
df_copy.loc[df_copy['gender'] == '여자', 'gender'] = 0

 

df_copy.head()

 

df_copy = df.copy()
df_copy

 

def male_or_female(x):
    if x == '남자':
        return 1
    elif x == '여자':
        return 0
    else:
        return None

 

print(male_or_female('남자'))
print(male_or_female('여자'))

 

df_copy['gender'].apply(male_or_female)

 

df_copy['gender'].apply(lambda x: 1 if x == '남자' else 0)

 

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

 

 

15. map 사용하기

Pandas의 map() 함수는 Series 객체에서 사용할 수 있는 함수로, 각 요소에 대해 함수나 매핑 규칙을 적용하여 새로운 값을 계산하거나 변환할 때 사용됩니다. map()은 데이터의 각 요소를 순회하며 특정 작업을 수행하므로, 데이터를 가공하거나 변환하는 데 유용합니다.

df_copy = df.copy()
df_copy

 

map_gender = {'남자':1, '여자':0}

 

df_copy['gender'].map(map_gender)

 

df_copy['NewGender'] = df_copy['성별'].map(map_gender)
df_copy.head()

 

 

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

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

 

df1

 

df1['파이썬'].dtypes

 

type(df1['파이썬'])

 

df1['파이썬'] + df1['데이터분석'] + df1['머신러닝딥러닝']

 

# df1에 총점, 평균이라는 파생변수를 만들고 파생변수에 총점, 평균을 구해서 저장
df1['총점'] = df1['파이썬'] + df1['데이터분석'] + df1['머신러닝딥러닝']
df1['평균'] = df1['총점'] / 3
df1

 

df1['파이썬'].sum() # df1['파이썬'].sum(axis=0)

 

df1['파이썬'].mean()

 

df1.sum()

 

df1.mean()

 

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

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

 

# df1 + df2 # TypeError: unsupported operand type(s) for +: 'int' and 'str'
df1 + 10
# df2 + 10 # TypeError: can only concatenate str (not "int") to str

 

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

df2 = pd.DataFrame({
    '데이터분석':[40, 60, 70, 55],
    '머신러닝딥러닝':[35, 40, 30, 70]
})

 

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

 

 

17. select_dtypes

df_copy = df.copy()
df_copy

 

df.info()

 

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

 

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]

 

 

18. get_dummies

get_dummies()는 Pandas에서 범주형 데이터를 원-핫 인코딩(one-hot encoding) 방식으로 변환하는 데 사용됩니다.

 

원-핫 인코딩

원-핫 인코딩은 각 범주를 별도의 열로 변환하고, 해당 범주에 해당하는 곳에 1을, 나머지에는 0을 채우는 방식입니다. 예를 들어, 데이터가 "Red", "Green", "Blue"와 같은 문자열이라면, 모델은 이를 이해하지 못합니다. 범주형 데이터를 숫자로 변환해야 모델이 계산할 수 있습니다. 원-핫 인코딩은 범주형 데이터를 숫자로 변환하면서도 각 범주 간의 순서나 크기를 부여하지 않습니다.

blood_map = {'A':0, 'B':1, 'AB':2, 'O':3}
df['Blood_code'] = df['Blood'].map(blood_map) # 라벨 인코딩
df.head()

 

pd.get_dummies(df['Blood'])

 

df = pd.get_dummies(df, columns=['Blood'])
df

 

df.info()

'인공지능 > LLM 서비스 개발' 카테고리의 다른 글

넘파이  (4) 2025.07.17
Fast API  (0) 2025.07.17
프롬프팅  (2) 2025.07.16
Gradio  (0) 2025.07.16
크롤링  (3) 2025.07.15