티스토리 뷰
학습목표
- Pandas의 핵심 데이터 구조인 DataFrame과 Series를 이해한다.
- 데이터 처리 및 분석에 필요한 Pandas 함수와 메서드를 학습한다.
- 데이터를 정리, 필터링, 변환, 요약하는 방법을 실습한다.
1. Pandas 란?
Pandas는 파이썬(Python)에서 데이터셋의 데이터 분석, 정리, 탐색과 조작을 위해 널리 사용되는 라이브러리이다.
Pandas는 구조화된 데이터를 효율적으로 다룰 수 있는 다양한 도구를 제공하며, 데이터 분석에서 중요한 역할을 한다.
기원:
"Pandas"라는 이름은 **"Panel Data"**와 **"Python Data Analysis"**를 의미한다.
2008년 Wes McKinney가 개발하였다.
Pandas의 주요 특징
- 다양한 데이터 형식 지원
- CSV, Excel, SQL, JSON 등의 파일 형식을 읽고 쓸 수 있다.
- 강력한 데이터 구조
- Series: 1차원 데이터 구조로, 라벨이 있는 배열.
- DataFrame: 2차원 데이터 구조로, 행과 열로 구성된 데이터.
- 유연한 데이터 조작
- 결측값 처리, 데이터 필터링, 변환, 그룹화 등 다양한 작업 가능.
- 통합 데이터 분석
- 간단한 통계 계산과 데이터 요약 제공.
- 다른 데이터 시각화 및 분석 라이브러리와 연계 가능(Matplotlib, NumPy 등)
여기서 잠깐!
데이터 과학이란?
컴퓨터 과학의 한 분야로, 데이터를 저장, 분석, 활용하여 유용한 정보를 추출하는 방법을 연구한다.
Pandas로 할 수 있는 일
Pandas는 데이터를 분석하여 다음 질문에 답할 수 있다:
- 두 개 이상의 열 사이에 상관관계가 있는가?
- 평균 값은 얼마인가?
- 최대값과 최소값은 무엇인가?
- 추가 기능: 데이터 정리
- 비어 있거나(NULL) 잘못된 값을 제거한다.
- 데이터셋을 더 읽기 쉽고 유용하게 변환한다.
참고사이트
pandas - Python Data Analysis Library
pandas pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language. Install pandas now!
pandas.pydata.org
https://github.com/pandas-dev/pandas
GitHub - pandas-dev/pandas: Flexible and powerful data analysis / manipulation library for Python, providing labeled data struct
Flexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more - pandas-dev/pandas
github.com
pandas 설치와 실행
pip install pandas
import pandas
import pandas as pd
예:
import pandas
mydataset = {
'cars': ["BMW", "Volvo", "Ford"],
'passings': [3, 7, 2]
}
myvar = pandas.DataFrame(mydataset)
print(myvar)
2. Pandas 데이터 구조: Series와 DataFrame
Pandas Series
- Pandas의 Series는 테이블의 한 열과 같은 역할을 하며, 1차원 배열로 데이터를 저장한다.
- Series는 숫자, 문자열, 불리언 등 어떤 데이터 타입도 저장할 수 있다.
Series의 주요 특징
- 1차원 데이터 구조:
- 데이터가 순차적으로 저장됨.
- 리스트와 비슷한 구조이지만, 인덱스와 함께 동작.
- 인덱스 레이블:
- 각 값은 고유한 인덱스(index)로 구분됨.
- 기본적으로 0부터 시작하는 숫자 인덱스를 사용하지만, 사용자 지정 레이블을 설정할 수도 있음.
기본 Series 생성
import pandas as pd
# 리스트로 Series 생성
a = [1, 7, 2]
myvar = pd.Series(a)
print(myvar)
0 1
1 7
2 2
dtype: int64
- 왼쪽의 숫자(0, 1, 2)는 기본 인덱스를 나타냄.
- 오른쪽 값(1, 7, 2)은 Series의 데이터
인덱스를 사용한 값 접근
# 첫 번째 값 접근
print(myvar[0])
1
사용자 정의 레이블
import pandas as pd
# 인덱스를 사용자 정의
a = [1, 7, 2]
myvar = pd.Series(a, index=["x", "y", "z"])
print(myvar)
x 1
y 7
z 2
dtype: int64
# 레이블 "y"의 값 접근
print(myvar["y"])
Series를 사용하는 이유
- 유연성: 숫자 인덱스와 레이블을 동시에 지원하여 데이터 접근이 쉬움.
- 다양한 데이터 타입: 숫자, 문자열, 불리언, 날짜 등 여러 타입을 저장 가능.
- Pandas DataFrame의 기본 구성 요소: DataFrame의 열(column)은 각각 Series로 구성됨.
DataFrame
- Pandas의 DataFrame은 2차원 데이터 구조로, 행(row)과 열(column)로 구성된 표와 유사하다.
- 이는 2차원 배열이나 스프레드시트 테이블과 같은 형식으로 데이터를 표현할 수 있도록 한다.
DataFrame의 주요 특징
- 구조:
- 행(row): 데이터의 각 관측값.
- 열(column): 데이터의 각 속성(변수).
- 행과 열에는 각각 고유한 **인덱스(index)**와 **이름(label)**이 있다.
- 유연한 데이터 조작:
- 행, 열의 선택 및 수정이 쉽다.
- 다양한 데이터 형식을 처리할 수 있다(CSV, Excel, JSON 등).
- 예제: 간단한 DataFrame 생성
import pandas as pd
# 딕셔너리를 사용해 DataFrame 생성
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
# DataFrame 생성
df = pd.DataFrame(data)
print(df)
calories duration
0 420 50
1 380 40
2 390 45
- 열(calories, duration)은 딕셔너리의 키를 기준으로 생성.
- 행(0, 1, 2)은 자동으로 기본 인덱스가 할당됨.
특정 행 선택
- 예제 1: 단일 행 선택
# loc를 사용하여 0번째 행 선택
print(df.loc[0])
calories 420
duration 50
Name: 0, dtype: int64
* 결과는 Pandas Series 객체로 반환됨.
- 예제 2: 여러 행 선택
# 0번째와 1번째 행 선택
print(df.loc[[0, 1]])
calories duration
0 420 50
1 380 40
- 결과는 Pandas DataFrame 객체로 반환됨.
DataFrame이 중요한 이유
- 데이터 분석과 조작:
- 데이터를 쉽게 정리, 필터링, 변환, 요약 가능.
- 다양한 파일 형식 지원:
- CSV, Excel, SQL, JSON 등의 데이터를 직접 읽고 처리 가능.
- 고급 데이터 분석:
- 수치 연산, 그룹화, 통계 분석 등 강력한 기능 제공.
Named Indexes (명명된 인덱스)
- Pandas에서는 index 인자를 사용하여 각 행에 고유한 이름을 지정할 수 있다. 이렇게 하면 기본 숫자 인덱스 대신 사용자가 정의한 이름으로 행을 식별할 수 있다.
import pandas as pd
# 데이터 정의
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
# Named Index를 사용하여 DataFrame 생성
df = pd.DataFrame(data, index=["day1", "day2", "day3"])
print(df)
calories duration
day1 420 50
day2 380 40
day3 390 45
Named Index를 사용한 특정 행 선택
# Named Index로 특정 행 선택
print(df.loc["day2"])
calories 380
duration 40
Name: day2, dtype: int64
- loc 속성을 사용하여 명명된 인덱스로 데이터를 선택할 수 있다.
- 반환 결과는 Pandas Series 객체이다.
CSV 파일에서 DataFrame 로드
Pandas는 외부 데이터 파일(예: CSV 파일)을 DataFrame으로 읽을 수 있다.
import pandas as pd
# CSV 파일 읽기
df = pd.read_csv('data.csv')
# 데이터 출력
print(df)
- pd.read_csv(): CSV 파일을 읽어 DataFrame으로 변환.
- 파일의 데이터는 열(column)과 행(row)으로 구성되어 DataFrame에 저장된다.
퀴즈
DataFrame은 행과 열이 있는 표와 같습니다.
3. Pandas의 기본 기능
Pandas Read CSV : CSV, Excel 파일 등의 외부 데이터를 읽고 처리할 수 있다.
- CSV 파일은 Comma Separated Values(콤마로 구분된 값) 형식의 텍스트 파일로, 데이터를 저장하는 간단한 방식이다.
- Pandas는 CSV 파일을 읽어 DataFrame 형태로 불러올 수 있다.
import pandas as pd
# CSV 파일 읽기
df = pd.read_csv('data.csv')
# DataFrame 출력
print(df)
to_string() 메서드로 전체 데이터 출력
- to_string(): DataFrame의 모든 행과 열을 문자열 형식으로 출력
import pandas as pd
# CSV 파일 읽기
df = pd.read_csv('data.csv')
# DataFrame 전체 출력
print(df.to_string())
Pandas의 기본 행 출력 설정
- 기본적으로 Pandas는 최대 60행만 출력하며, 그 이상일 경우 처음 5행과 마지막 5행만 표시한다.
import pandas as pd
# 최대 행 수 확인
print(pd.options.display.max_rows)
최대 행 수 변경 : pd.options.display.max_rows: 출력할 최대 행 수를 설정
예제: 최대 출력 행 수 늘리기
import pandas as pd
# 최대 행 수 설정 변경
pd.options.display.max_rows = 9999
# CSV 파일 읽기
df = pd.read_csv('data.csv')
# DataFrame 출력
print(df)
4. Pandas - Analyzing DataFrames
Pandas는 DataFrame의 데이터를 분석하고 요약하는 데 유용한 다양한 기능을 제공한다. 데이터프레임 분석은 데이터의 구조를 이해하고 통계적 통찰을 얻는 데 중요한 단계이다.
1. 데이터 구조 확인
(1) 데이터의 상위/하위 행 확인
- 데이터의 처음 5개 행을 출력:
print(df.head())
- 데이터의 마지막 5개 행을 출력:
print(df.tail())
- 특정 개수의 행 출력:
print(df.head(10)) # 처음 10개 행 출력
(2) 데이터 정보 확인
- 데이터프레임의 요약 정보 출력:
print(df.info())
출력 내용: 행과 열의 개수. 각 열의 데이터 타입. 결측값의 개수.
- 데이터프레임의 행렬 크기 확인:
print(df.shape) # (행 개수, 열 개수)
(3) 열 이름과 데이터 타입 확인
- 열 이름 확인:
print(df.columns)
- 열 데이터 타입 확인:
print(df.dtypes)
2. 데이터 요약 통계
(1) 기본 통계 요약
print(df.describe())
age salary
count 100.0 100.000
mean 35.6 75000.000
std 10.2 15000.000
min 18.0 50000.000
25% 27.5 65000.000
50% 35.0 75000.000
75% 43.0 85000.000
max 60.0 100000.000
(2) 특정 열의 통계 분석
print(df["age"].mean()) # 평균값
print(df["age"].median()) # 중앙값
print(df["age"].min()) # 최소값
print(df["age"].max()) # 최대값
3. 특정 데이터 선택
(1) 특정 열 선택
print(df["salary"]) # 'salary' 열 선택
(2) 조건부 필터링
# 'age'가 30 이상인 행 선택
filtered_df = df[df["age"] >= 30]
print(filtered_df)
(3) 특정 행 선택
# loc를 사용하여 인덱스 0번 행 선택
print(df.loc[0])
# 여러 행 선택
print(df.loc[[0, 1, 2]])
4. 결측값 처리 및 중복데이터 제거
print(df.isnull().sum()) # 각 열의 결측값 개수 출력
df["salary"].fillna(0, inplace=True) # 결측값을 0으로 채움
df.dropna(inplace=True) # 결측값이 포함된 행 삭제
중복 데이터 제거하기
- keep = 'first', 'last', False 등과 같은 매개변수를 사용해서 중복을 제거할 수 있다.
df = df.drop_duplicates(subset="a", keep='last')
df
중복이 있었던 6,9,12는 keep='last'를 사용했으므로 앞에 값이 남고 뒤에 중복되는 값은 삭제된 것을 알 수 있다.
5. 데이터 정렬
df_sorted = df.sort_values(by="age", ascending=True) # 'age' 기준 오름차순 정렬
print(df_sorted)
6. 그룹화 및 집계
(1) 그룹화
grouped = df.groupby("department").mean() # 부서별 평균값 계산
print(grouped)
(2) 특정 그룹 통계
sales_avg = df[df["department"] == "Sales"]["salary"].mean() # 'Sales' 부서의 평균 급여
print(sales_avg)
Pandas 데이터 분석 순서 요약
단계 | 설명 | 사용함수 | 예제코드 |
1. 데이터 구조 확인 | 데이터프레임의 기본 정보를 확인하여 데이터 구조를 이해 | info(), head(), tail(), shape, columns | print(df.info()), print(df.head()), print(df.shape) |
2. 요약 통계 계산 | 각 열의 기본 통계량을 계산하여 데이터를 요약 | describe(), mean(), median(), min(), max() | print(df.describe()), print(df["age"].mean()) |
3. 데이터 선택 | 조건에 맞는 행이나 열을 선택하여 원하는 데이터만 추출 | loc, iloc, 조건 필터링 | print(df.loc[0]), filtered = df[df["age"] > 30] |
4. 결측값 처리 | 결측값을 확인하고 채우거나 제거하여 데이터를 정리 | isnull(), fillna(), dropna() | print(df.isnull().sum()), df["salary"].fillna(0, inplace=True), df.dropna(inplace=True) |
5. 데이터 정렬 | 특정 열 기준으로 데이터를 정렬하여 분석에 필요한 순서대로 정리 | sort_values() | df_sorted = df.sort_values(by="age", ascending=True) |
6. 그룹화 및 집계 | 데이터를 특정 기준으로 그룹화하고 집계하여 패턴을 분석 | groupby() | grouped = df.groupby("department").mean(), sales_avg = df[df["department"] == "Sales"]["salary"].mean() |
import pandas as pd
# 예제 데이터
data = {
"department": ["Sales", "IT", "Sales", "HR", "IT"],
"age": [25, 30, 35, 40, None],
"salary": [50000, 70000, 60000, 80000, None]
}
df = pd.DataFrame(data)
# 1. 데이터 구조 확인
print(df.info())
print(df.head())
# 2. 요약 통계 계산
print(df.describe())
print("평균 나이:", df["age"].mean())
# 3. 데이터 선택
filtered = df[df["age"] > 30]
print("30세 이상 직원:\n", filtered)
# 4. 결측값 처리
print("결측값 개수:\n", df.isnull().sum())
df["age"].fillna(df["age"].mean(), inplace=True) # 나이의 결측값을 평균으로 대체
df["salary"].fillna(0, inplace=True) # 급여의 결측값을 0으로 대체
print("결측값 처리 후 데이터:\n", df)
# 5. 데이터 정렬
df_sorted = df.sort_values(by="salary", ascending=False)
print("급여 기준 내림차순 정렬:\n", df_sorted)
# 6. 그룹화 및 집계
grouped = df.groupby("department").mean()
print("부서별 평균 데이터:\n", grouped)
5. str 접근자로 문자열 다루기
판다스의 시리즈 형태의 데이터를 문자열로 다루게 되면 파이썬 문자열 함수와 비슷하게 문자열을 처리할 수 있다.
다음과 같은 문서가 판다스의 시리즈 형태로 있다고 할 때 대소문자 변경, 공백제거, 어절 나누기, 특정문자 찾기, 바꾸기 등의 문자열 전처리에 필요한 몇 가지 기능을 알아본다.
Pandas에서 Series 데이터를 문자열로 처리할 때는 str 접근자를 사용하여 파이썬의 문자열 메서드와 유사한 방식으로 데이터를 조작할 수 있다.
# 실습용 예시 문장
document = [
"온라인 강의 등록 관련 문의입니다.",
" 학원 운영 시간 문의입니다. ",
"교통 카드 발급에 관한 문의입니다. ",
"코로나 확산으로 인한 운영 변경 안내입니다.",
"Online course 관련 질문입니다.",
" Taxi 운임 관련 문의입니다. ",
"버스 노선 변경 관련 문의입니다. "
]
위에 코드로 실습을 위해 예시 문장을 몇 개 만들어서 document에 담아 둔다. 그런 다음 document를 pd 데이터 프레임 안에 괄호로 감싸서 변수 df_doc에 할당할 것이다. 첫 행에 "문서"라는 제목도 설정한다
df_doc = pd.DataFrame(document, columns=["문서"])
df_doc
1. 공백 제거: 앞뒤 또는 중간에 있는 불필요한 공백을 제거.
document = [doc.strip() for doc in document]
print(document)
df["Trimmed"] = df["Text"].str.strip()
df["Left Trimmed"] = df["Text"].str.lstrip()
df["Right Trimmed"] = df["Text"].str.rstrip()
print(df[["Text", "Trimmed", "Left Trimmed", "Right Trimmed"]])
2. 특정 단어 포함 여부: 특정 키워드(예: "문의", "강의") 포함 여부 확인.
- str.contains("찾고자 하는 문자")를 입력하면 문자가 있는 열은 True, 없는 열은 False를 반환한다.
contains_question = [doc for doc in document if "문의" in doc]
print(contains_question)
3. 문자열 치환: "Online"을 "온라인"으로 변경
document = [doc.replace("Online", "온라인") for doc in document]
print(document)
4. 토큰화: 문장을 단어 단위로 나누기.
tokenized = [doc.split() for doc in document]
print(tokenized)
5. 데이터 타입 변경 : astype()을 사용해서 df_doc의 각 행에 들어있는 데이터의 타입을 바꿀 수 있다.
df_doc['문서'].astype('string')
- Name: 문서, dtype: string으로 데이터의 타입이 변경되었음을 확인할 수 있다.
6. 대소문자 변경
df["Uppercase"] = df["Text"].str.upper() # 영어 대문자 변환
df["Lowercase"] = df["Text"].str.lower() # 영어 소문자 변환
print(df[["Text", "Uppercase", "Lowercase"]])
츨력 결과를 보면 첫 글자만 대문자로 되어 있던 Bus와 Taxi가 Series.str.upper()로 변경한 후에는 모두 대문자인 BUS, TAXI 로 바뀌었다. Series.str.lower()로 변경한 후에는 모두 소문자인 bus, taxi로 변경된 것을 확인할 수 있을것이다.
# 소문자로 변경하기
df_doc["문서"].str.lower()
Pandas str 접근자 주요 기능 요약
기능 | 메서드 | 설명 | 예제코드 |
대소문자 변환 | str.upper() | 문자열을 모두 대문자로 변환 | df["Text"].str.upper() |
str.lower() | 문자열을 모두 소문자로 변환 | df["Text"].str.lower() | |
str.capitalize() | 문자열의 첫 글자를 대문자로 변환 | df["Text"].str.capitalize() | |
공백 제거 | str.strip() | 문자열 양쪽의 공백 제거 | df["Text"].str.strip() |
str.lstrip() | 문자열 왼쪽의 공백 제거 | df["Text"].str.lstrip() | |
str.rstrip() | 문자열 오른쪽의 공백 제거 | df["Text"].str.rstrip() | |
어절 나누기 | str.split() | 문자열을 단어 단위로 나눔 (기본 공백 기준) | df["Text"].str.split() |
str.split(",") | 지정한 구분자를 기준으로 문자열을 나눔 | df["Text"].str.split(",") | |
특정 문자 찾기 | str.contains() | 문자열에 특정 패턴이 포함되었는지 확인 | df["Text"].str.contains("Pandas") |
str.find() | 특정 문자열의 시작 위치 반환 (없으면 -1) | df["Text"].str.find("data") | |
특정 문자 바꾸기 | str.replace() | 특정 문자열을 다른 문자열로 대체 | df["Text"].str.replace("Pandas", "Python") |
문자열 길이 확인 | str.len() | 각 문자열의 길이 반환 | df["Text"].str.len() |
정규표현식 활용 | str.contains(regex) | 정규표현식을 사용하여 특정 패턴이 포함되었는지 확인 | df["Text"].str.contains(r"\bis\b", regex=True) |
str.replace(regex) | 정규표현식을 사용하여 특정 패턴을 다른 문자열로 대체 | df["Text"].str.replace(r"\d+", "", regex=True) | |
대소문자 변환 | str.title() | 각 단어의 첫 글자를 대문자로 변환 | df["Text"].str.title() |
문자열 확인 | str.startswith() | 문자열이 특정 문자로 시작하는지 확인 | df["Text"].str.startswith("Hello") |
str.endswith() | 문자열이 특정 문자로 끝나는지 확인 | df["Text"].str.endswith("!") |
과제 및 실습
실습 1: CSV 파일에서 데이터를 읽어 특정 조건의 데이터를 필터링하고 요약 통계를 작성.
Name,Age,Department,Salary
Alice,25,Sales,50000
Bob,30,IT,70000
Charlie,35,HR,60000
David,40,Sales,80000
Eve,29,IT,72000
Frank,50,HR,90000
Grace,45,Sales,85000
import pandas as pd
# 1. CSV 파일 읽기
df = pd.read_csv("example.csv")
# 데이터 확인
print("원본 데이터:\n", df)
# 2. 조건 필터링: 나이가 30세 이상인 직원 선택
filtered_df = df[df["Age"] >= 30]
print("\n30세 이상 직원 데이터:\n", filtered_df)
# 3. 요약 통계 계산: 평균 나이와 급여 계산
average_age = filtered_df["Age"].mean()
average_salary = filtered_df["Salary"].mean()
print("\n30세 이상 직원의 요약 통계:")
print(f"평균 나이: {average_age}")
print(f"평균 급여: {average_salary}")
- 원본 데이터 출력:
Name Age Department Salary
0 Alice 25 Sales 50000
1 Bob 30 IT 70000
2 Charlie 35 HR 60000
3 David 40 Sales 80000
4 Eve 29 IT 72000
5 Frank 50 HR 90000
6 Grace 45 Sales 85000
- 필터링된 데이터:
Name Age Department Salary
1 Bob 30 IT 70000
2 Charlie 35 HR 60000
3 David 40 Sales 80000
5 Frank 50 HR 90000
6 Grace 45 Sales 85000
- 요약 통계 결과:
30세 이상 직원의 요약 통계:
평균 나이: 40.0
평균 급여: 77000.0
실습 2: Pandas를 이용하여 결측값을 처리하고 시각화를 생성.
import pandas as pd
import matplotlib.pyplot as plt
# 1. CSV 파일 읽기
df = pd.read_csv("missing_data.csv")
# 데이터 확인
print("원본 데이터:\n", df)
# 2. 결측값 처리
# 결측값 확인
print("\n결측값 개수:\n", df.isnull().sum())
# 결측값 채우기
df["Age"].fillna(df["Age"].mean(), inplace=True) # 나이 결측값을 평균으로 대체
df["Salary"].fillna(0, inplace=True) # 급여 결측값을 0으로 대체
print("\n결측값 처리 후 데이터:\n", df)
# 3. 시각화: 부서별 평균 급여
average_salary_by_department = df.groupby("Department")["Salary"].mean()
# 바 차트 생성
average_salary_by_department.plot(kind="bar", title="Average Salary by Department", ylabel="Average Salary")
plt.show()
- 원본 데이터
Name Age Department Salary
0 Alice 25.0 Sales 50000.0
1 Bob 30.0 IT 70000.0
2 Charlie NaN HR 60000.0
3 David 40.0 Sales 80000.0
4 Eve 29.0 IT NaN
5 Frank 50.0 HR 90000.0
6 Grace 45.0 Sales 85000.0
- 결측값 개수
결측값 개수:
Name 0
Age 1
Department 0
Salary 1
dtype: int64
- 결측값 처리 후 데이터
Name Age Department Salary
0 Alice 25.000000 Sales 50000.0
1 Bob 30.000000 IT 70000.0
2 Charlie 36.428571 HR 60000.0
3 David 40.000000 Sales 80000.0
4 Eve 29.000000 IT 0.0
5 Frank 50.000000 HR 90000.0
6 Grace 45.000000 Sales 85000.0
- 시각화
import pandas as pd
import matplotlib.pyplot as plt
# 데이터셋
data = {
"Name": ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace"],
"Age": [25, 30, None, 40, 29, 50, 45],
"Department": ["Sales", "IT", "HR", "Sales", "IT", "HR", "Sales"],
"Salary": [50000, 70000, 60000, 80000, None, 90000, 85000]
}
df = pd.DataFrame(data)
# 결측값 처리
df["Age"].fillna(df["Age"].mean(), inplace=True)
df["Salary"].fillna(0, inplace=True)
# 부서별 평균 급여 계산
average_salary_by_department = df.groupby("Department")["Salary"].mean()
# 바 차트 생성
average_salary_by_department.plot(kind="bar", title="Average Salary by Department", ylabel="Average Salary", xlabel="Department")
plt.xticks(rotation=0)
plt.show()
실습 3: 그룹화된 데이터의 통계를 계산하고 이를 Excel 파일로 저장.
아래는 Pandas를 이용하여 그룹화된 데이터의 통계를 계산한 후, 이를 Excel 파일로 저장하는 실습 예제이다.
import pandas as pd
# 데이터셋 생성
data = {
"Name": ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace"],
"Age": [25, 30, 35, 40, 29, 50, 45],
"Department": ["Sales", "IT", "HR", "Sales", "IT", "HR", "Sales"],
"Salary": [50000, 70000, 60000, 80000, 72000, 90000, 85000]
}
# DataFrame 생성
df = pd.DataFrame(data)
# 1. 그룹화된 데이터 통계 계산
grouped = df.groupby("Department").agg(
Average_Salary=("Salary", "mean"),
Total_Salary=("Salary", "sum"),
Average_Age=("Age", "mean"),
Count=("Name", "count")
)
# 그룹화된 데이터 출력
print("그룹화된 데이터:\n", grouped)
# 2. 그룹화된 데이터를 Excel 파일로 저장
output_file = "grouped_statistics.xlsx"
grouped.to_excel(output_file, sheet_name="Statistics")
print(f"\nExcel 파일로 저장 완료: {output_file}")
과제 : 타이타닉 데이터셋을 활용하여 Pandas를 이용한 데이터 분석
1. 데이터 준비 : 타이타닉 데이터셋 로드
import pandas as pd
# 타이타닉 데이터셋 로드
url = "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
df = pd.read_csv(url)
# 데이터 확인
print(df.head()) # 상위 5개 데이터 출력
1단계: 데이터 구조 확인
# 데이터프레임 정보 확인
print(df.info())
# 데이터 크기 확인 (행, 열)
print(df.shape)
# 열 이름 확인
print(df.columns)
2단계: 요약 통계 계산 : 나이(Age)와 요금(Fare) 등 수치 데이터의 기본 통계 계산.
# 전체 데이터의 요약 통계
print(df.describe())
# 특정 열의 평균, 최대값, 최소값 계산
print("평균 나이:", df["Age"].mean())
print("최소 나이:", df["Age"].min())
print("최대 나이:", df["Age"].max())
3단계: 데이터 선택 : 특정 조건(예: 1등석 승객)의 데이터를 선택.
# 특정 열 선택
print(df["Name"].head()) # 승객 이름
# 조건에 맞는 데이터 필터링: 1등석 승객만 선택
first_class = df[df["Pclass"] == 1]
print(first_class.head())
# 특정 행 선택
print(df.loc[0]) # 첫 번째 승객 데이터
4단계: 결측값 처리 : Age 결측값을 평균으로 대체하고, Cabin 결측값이 있는 행을 제거.
# 결측값 확인
print("결측값 개수:\n", df.isnull().sum())
# 결측값 채우기: Age 열의 결측값을 평균으로 채움
df["Age"].fillna(df["Age"].mean(), inplace=True)
# 결측값 삭제: Cabin 열이 비어 있는 행 제거
df.dropna(subset=["Cabin"], inplace=True)
# 결측값 처리 후 확인
print("결측값 처리 후:\n", df.isnull().sum())
5단계: 데이터 정렬 : 나이와 요금을 기준으로 데이터 정렬.
# 나이를 기준으로 데이터 정렬 (오름차순)
sorted_df = df.sort_values(by="Age", ascending=True)
print(sorted_df.head())
# 요금을 기준으로 내림차순 정렬
sorted_by_fare = df.sort_values(by="Fare", ascending=False)
print(sorted_by_fare.head())
6단계: 그룹화 및 집계 : 객실 등급별 평균 요금과 성별 생존률 계산.
# Pclass(객실 등급)별 평균 요금
grouped = df.groupby("Pclass")["Fare"].mean()
print("객실 등급별 평균 요금:\n", grouped)
# 성별(Sex)별 생존률(Survived의 평균)
survival_by_gender = df.groupby("Sex")["Survived"].mean()
print("성별 생존률:\n", survival_by_gender)
추가 분석 1: 성별 생존률 비교
타이타닉 데이터에서 성별에 따른 생존률을 분석하고 시각화.
import pandas as pd
import matplotlib.pyplot as plt
# 타이타닉 데이터셋 로드
url = "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
df = pd.read_csv(url)
# 성별에 따른 생존률 계산
survival_by_gender = df.groupby("Sex")["Survived"].mean()
print("성별 생존률:\n", survival_by_gender)
# 시각화
survival_by_gender.plot(kind="bar", color=["blue", "orange"], title="Survival Rate by Gender", ylabel="Survival Rate", xlabel="Gender")
plt.xticks(rotation=0)
plt.show()
- 남성(Male) 생존률: 약 19%
- 여성(Female) 생존률: 약 74%
추가 분석 2: 객실 등급(Pclass)에 따른 평균 생존률과 요금 비교
객실 등급별 평균 생존률과 평균 요금을 계산.
# Pclass(객실 등급)별 평균 생존률과 평균 요금
pclass_stats = df.groupby("Pclass").agg(
Survival_Rate=("Survived", "mean"),
Average_Fare=("Fare", "mean")
)
print("\n객실 등급별 생존률과 평균 요금:\n", pclass_stats)
# 시각화
pclass_stats.plot(kind="bar", subplots=True, layout=(1, 2), figsize=(12, 6), title=["Survival Rate by Pclass", "Average Fare by Pclass"])
plt.tight_layout()
plt.show()
- 1등급 생존률: 약 63%
- 2등급 생존률: 약 47%
- 3등급 생존률: 약 24%
- 평균 요금은 1등급이 가장 높고, 3등급이 가장 낮음.
추가 분석 3: 나이(Age)에 따른 생존 여부 시각화
나이에 따른 생존자와 사망자를 산점도로 시각화.
# 결측값 처리 (Age의 결측값을 평균으로 대체)
df["Age"].fillna(df["Age"].mean(), inplace=True)
# 생존 여부에 따라 색상을 다르게 산점도로 표현
plt.figure(figsize=(10, 6))
plt.scatter(df[df["Survived"] == 1]["Age"], df[df["Survived"] == 1]["Fare"], c="green", label="Survived", alpha=0.6)
plt.scatter(df[df["Survived"] == 0]["Age"], df[df["Survived"] == 0]["Fare"], c="red", label="Not Survived", alpha=0.6)
plt.title("Age vs Fare: Survived vs Not Survived")
plt.xlabel("Age")
plt.ylabel("Fare")
plt.legend()
plt.show()
- 생존자는 대체로 다양한 나이대에서 고른 분포를 보임.
- 고가의 요금을 지불한 경우 생존 확률이 높은 경향.
추가 분석 4: 자녀/배우자(SibSp) 유무에 따른 생존률
가족 동반 여부(SibSp 값이 0인지 여부)에 따른 생존률을 계산.
# 가족 동반 여부(SibSp) 생존률 계산
family_survival = df.groupby(df["SibSp"] > 0)["Survived"].mean()
family_survival.index = ["No Family", "With Family"]
print("\n가족 동반 여부에 따른 생존률:\n", family_survival)
# 시각화
family_survival.plot(kind="bar", color=["red", "blue"], title="Survival Rate by Family Status", ylabel="Survival Rate")
plt.xticks(rotation=0)
plt.show()
요약
- 성별 생존률: 여성 생존률이 남성보다 훨씬 높음.
- 객실 등급: 등급이 높을수록 생존률과 요금이 높음.
- 나이와 요금: 나이에 따른 생존률은 고른 분포를 보이며, 요금이 높은 승객이 더 많이 생존.
- 가족 동반: 가족과 함께 탑승한 승객의 생존률이 더 높음.
공공데이터를 활용한 Pandas 문자열 정리 및 데이터 분석 연습 예제
다음은 공공데이터를 기반으로 Pandas 문자열 정리와 데이터 분석을 연습할 수 있는 예제입니다. 이를 통해 데이터를 정리하고, 필요한 정보를 추출하며, 시각화까지 연습할 수 있습니다.
주제: 공공기관에서 제공하는 대중교통 정보 데이터 (예시 데이터)
import pandas as pd
# 예제 데이터 생성
data = {
"Route": ["101번 버스", "M234 지하철", "TAXI 운임", "405 버스", "지하철 2호선", "택시 승차장"],
"Description": [
"서울-강남 노선입니다.",
"광역버스 환승 구간 안내입니다.",
"기본 운임은 3800원입니다.",
"수도권 외곽 순환 버스입니다.",
"서울 2호선 전구간 안내입니다.",
"택시 이용 시 유의사항입니다."
]
}
df = pd.DataFrame(data)
print(df)
연습 주제 및 분석 아이디어
(1) 문자열 정리 : Route와 Description 열에서 앞뒤 공백 제거.
df["Route"] = df["Route"].str.strip()
df["Description"] = df["Description"].str.strip()
print(df)
한글, 숫자, 영어만 남기기: 정규표현식을 활용해 불필요한 특수문자 제거.
df["Route"] = df["Route"].str.replace(r"[^가-힣0-9a-zA-Z\s]", "", regex=True)
print(df)
특정 키워드 포함 여부 확인:Description 열에서 "노선"이라는 단어가 포함된 행 찾기.
df["Contains 노선"] = df["Description"].str.contains("노선")
print(df)
(2) 문자열 변환
대소문자 통일:모든 문자열을 소문자로 변환하여 데이터 정리.
df["Route"] = df["Route"].str.lower()
print(df)
특정 키워드 대체: Route 열에서 "버스"를 "BUS"로, "지하철"을 "SUBWAY"로 변경.
df["Route"] = df["Route"].str.replace("버스", "BUS").str.replace("지하철", "SUBWAY")
print(df)
(3) 데이터 분석
특정 카테고리별 빈도수 확인:"버스", "지하철", "택시"와 관련된 데이터의 빈도수 계산.
categories = ["버스", "지하철", "택시"]
for category in categories:
print(f"{category}: {df['Route'].str.contains(category).sum()}건")
키워드 기반 필터링: "운임"이 포함된 행 필터링.
fare_data = df[df["Description"].str.contains("운임")]
print(fare_data)
문자열 길이 분석: Description 열의 문자열 길이 계산.
df["Description Length"] = df["Description"].str.len()
print(df)
3. 분석 결과 시각화 빈도수 시각화:
import matplotlib.pyplot as plt
# 빈도수 계산
category_counts = {
"버스": df["Route"].str.contains("버스").sum(),
"지하철": df["Route"].str.contains("지하철").sum(),
"택시": df["Route"].str.contains("택시").sum()
}
# 막대그래프 그리기
plt.bar(category_counts.keys(), category_counts.values(), color=["skyblue", "orange", "green"])
plt.title("Category Frequency in Route")
plt.xlabel("Category")
plt.ylabel("Frequency")
plt.show()
- Total
- Today
- Yesterday