250807 [ Day 24 ] - Pandas (2)

TaeHyun·2025년 8월 7일

TIL

목록 보기
24/182

시작하며

오늘은 Pandas 2일차다. 오늘도 상당히 많은 내용을 다뤘지만, 어제 복습을 충분히 해서 그런지 아니면 오늘 내용이 상대적으로 쉬워서 그런지, 어제보다는 훨씬 수월하게 느껴졌다. 오늘 수업이 끝나고 Pandas를 공부할 수 있는 사이트를 추천해주셔서, 빨리 블로깅을 마치고 그 사이트에서 공부해보고 싶다.

조건 필터링

data = {
    '이름': ['홍길동', '김철수', '이영희', '박민수'],
    '점수': [90, 70, 95, 95],
    '반': [2, 1, 1, 2]
}
df = pd.DataFrame(data)
df
#   이름	   점수	반
# 0	홍길동	90	2
# 1	김철수	70	1
# 2	이영희	95	1
# 3	박민수	95	2

  • 일반적인 조건 사용
mask = df["점수"] >= 80
filtered = df[mask]
filtered
#   이름	   점수	반
# 0	홍길동	90	2
# 2	이영희	95	1
# 3	박민수	95	2

여러 조건의 결합

  • and : &
  • or : |
  • not : ~
  • isin() : 여러 값 중에 하나에 해당하는지 여부를 판단할 때 사용
mask = (df["반"] == 1) & (df["점수"] >= 80)
df[mask]
#   이름   점수	반
# 2	이영희	95	1

mask = (df["반"] == 2) | (df["점수"] >= 90)
df[mask]
#   이름	   점수	반
# 0	홍길동	90	2
# 2	이영희	95	1
# 3	박민수	95	2

msdk = (df["이름"] == "홍길동") | (df["이름"] == "박민수")

mask = df["이름"].isin(["홍길동", "박민수"])
df[mask]
#   이름 	점수	반
# 0	홍길동	90	2
# 3	박민수	95	2

mask = ~ df["이름"].isin(["홍길동", "박민수"])
df[mask]
#   이름	   점수	반
# 1	김철수	70	1
# 2	이영희	95	1

reset_index()

  • 조건 필터링, 정렬 등을 통해 인덱스가 변경 됐을시 인덱스 초기화 가능
  • 초기화시 index 컬럼이 생겨 기존 인덱스 저장
  • reset_index(drop=True) 를 사용하여 기존 인덱스 삭제 가능
mask = (df["반"] == 2) | (df["점수"] >= 90)
df2 = df[mask]
df2
#   이름   점수	반
# 0	홍길동	90	2
# 2	이영희	95	1
# 3	박민수	95	2

df2 = df2.reset_index()
df2
# index	이름    점수	 반
# 0	0	홍길동	90	 2
# 1	2	이영희	95 	 1
# 2	3	박민수	95 	 2

df2 = df2.reset_index(drop=True)
df2
#   이름   점수	반
# 0	홍길동	90	2
# 1	이영희	95	1
# 2	박민수	95	2

열 추가 및 수정, 삭제

df = pd.DataFrame({
    '이름': ['김철수', '이영희', '박민수'],
    '국어': [90, 80, 70],
    '영어': [85, 78, 92]
})
df
#   이름   국어	영어
# 0	김철수	90	85
# 1	이영희	80	78
# 2	박민수	70	92

열 추가

  • df[”컬럼명”] = “값”
  • 컬럼이 존재하면 수정, 컬럼이 존재하지 않으면 추가
  • 같은 값을 한번에 추가
df["반"] = "1반"
df
#   이름   국어	영어   반
# 0	김철수	90	85	  1반
# 1	이영희	80	78	  1반
# 2	박민수	70	92    1반

  • 조건문을 통한 추가
df["국어_합격여부"] = df["국어"] >= 80
df
#   이름   국어	영어  반  국어_합격여부
# 0	김철수	90	85	1반	True
# 1	이영희	80	78	1반	True
# 2	박민수	70	92	1반	False

  • 리스트/시리즈를 통한 열 추가
# 리스트/시리즈를 통한 열 추가
df["학번"] = [101, 102, 103]
df
#   이름   국어	영어  반 국어_합격여부	학번
# 0	김철수	90	85	1반	True		101
# 1	이영희	80	78	1반	True		102
# 2	박민수	70	92	1반	False		103

  • 시리즈의 연산 결과로 새 열 추가
df["총점"] = df["국어"] + df["영어"]
df
#   이름   국어	영어  반 국어_합격여부 학번	총점
# 0	김철수	90	85	1반	True		101	175
# 1	이영희	80	78	1반	True		102	158
# 2	박민수	70	92	1반	False		103	162

  • 새로운 컬럼 추가시, 행의 개수가 맞지 않으면 에러 발생
df["새로운 열"] = [1, 2]

열 수정

  • 기존 값을 한번에 변경
df["영어"] = 100
df
#   이름   국어	 영어 반 국어_합격여부 학번	    총점
# 0	김철수	90	100	1반	True		101		175
# 1	이영희	80	100	1반	True		102		158
# 2	박민수	70	100	1반	False		103		162

열 삭제

  • drop 사용
  • drop의 기본 값 = 0 이기 때문에, 열 삭제 시 axis=1 입력
  • 단일 열 삭제
df2 = df.drop("반", axis=1)
df2
#   이름   국어	영어 국어_합격여부 학번	총점
# 0	김철수	90	100	True		101		175
# 1	이영희	80	100	True		102		158
# 2	박민수	70	100	False		103		162

  • 여러 열 삭제
df3 = df2.drop(["총점", "국어_합격여부"], axis=1)
df3
#   이름   국어	영어  학번
# 0	김철수	90	100	  101
# 1	이영희	80	100	  102
# 2	박민수	70	100	  103

inplace=True

  • 원본을 변경
df.drop("반", axis=1, inplace=True)
df
#   이름   국어	영어 국어_합격여부 학번	총점
# 0	김철수	90	100	True		101		175
# 1	이영희	80	100	True		102		158
# 2	박민수	70	100	False		103		162

기타 삭제 방법

  • del : 원본 객체를 제거
del df["총점"]
df
#   이름   국어	영어 국어_합격여부 학번
# 0	김철수	90	100	True		101
# 1	이영희	80	100	True		102
# 2	박민수	70	100	False		103

  • pop() : 제거한 객체 반환
deleted = df.pop("국어_합격여부")
deleted
# 0     True
# 1     True
# 2    False
# Name: 국어_합격여부, dtype: bool

행 추가 및 수정, 삭제

df = pd.DataFrame({
    '이름': ['김철수', '이영희'],
    '나이': [23, 25]
})
df
#   이름   나이
# 0	김철수	23
# 1	이영희	25

행 추가

  • pd.concat()
new_row = pd.DataFrame([{"이름": "태현", "나이": 27}])

df = pd.concat([df, new_row])
df
#   이름	    나이
# 0	김철수	23
# 1	이영희	25
# 0	태현	    27

# 인덱스 재정렬
df = pd.concat([df, new_row], ignore_index=True)
df
#   이름	    나이
# 0	김철수	 23
# 1	이영희	 25
# 2	태현	     27

  • 여러 행 추가하기
new_rows = pd.DataFrame([{"이름": "태현", "나이": 27},
                        {"이름": "이름1", "나이": 22},
                        {"이름": "이름2", "나이": 26}])

df = pd.concat([df, new_rows], ignore_index=True)
df
#   이름	      나이
# 0	김철수	   23
# 1	이영희	   25
# 2	태현	       27
# 3	이름1	   22
# 4	이름2	   26

행 수정

  • loc, iloc 활용
df.loc[1] = ["김영희", 35]
df
#   이름	   나이
# 0	김철수	23
# 1	김영희	35
# 2	태현	    27
# 3	이름1	22
# 4	이름2	26

df.loc[0, "나이"] = 18
df
#   이름	   나이
# 0	김철수	18
# 1	김영희	35
# 2	태현	    27
# 3	이름1	22
# 4	이름2	26

  • 여러 값 한번에 수정하기
df.loc[1:3, "나이"] = 11, 12, 13
df
#   이름	   나이
# 0	김철수	18
# 1	김영희	11
# 2	태현	    12
# 3	이름1	13
# 4	이름2	26

df.loc[1:2, ["이름", "나이"]] = [["new1", 100], ["new2", 200]]
df
#   이름	     나이
# 0	김철수	 18
# 1	new1	100
# 2	new2	200
# 3	이름1	 13
# 4	이름2	 26

행 삭제

  • drop 사용
  • axis 기본값 = 0
  • 단일 행 삭제
df2 = df.drop(1).reset_index(drop=True)
df2
#   이름	    나이
# 0	김철수	 18
# 1	new2	200
# 2	이름1	 13
# 3	이름2	 26

  • 여러 행 삭제
df3 = df.drop([0, 2]).reset_index(drop=True)
df3
#   이름	    나이
# 0	new1	100
# 1	이름1	 13
# 2	이름2	 26

  • 조건을 이용한 삭제
df = df[df["나이"] >= 20]
df
#   이름	    나이
# 1	new1	100
# 2	new2	200
# 4	태현	     27
# 5	이름1	 22
# 6	이름2	 26

정렬

  • sort_values : 값 기준 정렬
  • sort_index : 인덱스 기준 정렬

sort_values

data = {
    '이름': ['홍길동', '김철수', '이영희', '박민수'],
    '점수': [90, 70, 85, 95],
    '반': [2, 1, 1, 2]
}
df = pd.DataFrame(data)
df
#   이름   점수	반
# 0	홍길동	90	2
# 1	김철수	70	1
# 2	이영희	85	1
# 3	박민수	95	2

  • 오름차순 정렬
df2 = df.sort_values(by="점수").reset_index(drop=True)
df2
#   이름   점수	반
# 0	김철수	70	1
# 1	이영희	85	1
# 2	홍길동	90	2
# 3	박민수	95	2

  • 내림차순 정렬
  • ascending=False = 내림차순
df3 = df.sort_values("점수", ascending=False).reset_index(drop=True)
df3
#   이름   점수	반
# 0	박민수	95	2
# 1	홍길동	90	2
# 2	이영희	85	1
# 3	김철수	70	1

  • 여러 기준을 사용하여 정렬
df4 = df.sort_values(["반", "점수"], ascending=[True, False]).reset_index(drop=True)
df4
#   이름   점수	반
# 0	이영희	85	1
# 1	김철수	70	1
# 2	박민수	95	2
# 3	홍길동	90	2

  • 원본 변경
df.sort_values(["반", "점수"], ascending=[True, False], inplace=True)
df.reset_index(drop=True)
#   이름   점수	반
# 0	이영희	85	1
# 1	김철수	70	1
# 2	박민수	95	2
# 3	홍길동	90	2

sort_index

df_shuffled = df.sample(frac=1, random_state=42)
df_shuffled
#   이름   점수	반
# 1	김철수	70	1
# 0	홍길동	90	2
# 2	이영희	85	1
# 3	박민수	95	2

  • 행 인덱스 기준으로 정렬
df5 = df_shuffled.sort_index()
df5
#   이름    점수 반
# 0	홍길동	90	2
# 1	김철수	70	1
# 2	이영희	85	1
# 3	박민수	95	2

  • 열 이름 기준 정렬 (알파벳순)
df6 = df5.sort_index(axis=1)
df6
#   반   이름	점수
# 0	2	홍길동	90
# 1	1	김철수	70
# 2	1	이영희	85
# 3	2	박민수	95

groupby

df = pd.DataFrame({
    'team': ['A', 'A', 'B', 'B', 'B', 'C'],
    'name': ['Kim', 'Lee', 'Park', 'Choi', 'Jung', 'Han'],
    'score': [90, 85, 80, 70, 95, 88]
})
df
# team	  name	   score
# 0	A	  Kim	    90
# 1	A	  Lee	    85
# 2	B  	  Park	    80
# 3	B	  Choi	    70
# 4	B  	  Jung	    95
# 5	C	  Han	    88

  • 그룹화 이후 집계함수를 적용하여 사용

단일 컬럼 기준 그룹화

grouped = df.groupby("team")

# 합계
result_sum = grouped["score"].sum()
result_sum
# team
# A    175
# B    245
# C     88
# Name: score, dtype: int64

# 평균
result_mean = grouped["score"].mean()
result_mean
# team
# A    87.500000
# B    81.666667
# C    88.000000
# Name: score, dtype: float64

# 개수
result_count = grouped["score"].count()
result_count
# team
# A    2
# B    3
# C    1
# Name: score, dtype: int64

여러 컬럼 기준 그룹화

df2 = pd.DataFrame({
    'team': ['A', 'A', 'B', 'B', 'B', 'C'],
    'gender': ['M', 'F', 'F', 'M', 'M', 'F'],
    'score': [90, 85, 80, 70, 95, 88]
})
df2
# team	gender	score
# 0	A	M	    90
# 1	A	F	    85
# 2	B	F	    80
# 3	B	M	    70
# 4	B	M	    95
# 5	C	F	    88
result = df2.groupby(["team", "gender"])["score"].mean()
result
# team  gender
# A     F         85.0
#       M         90.0
# B     F         80.0
#       M         82.5
# C     F         88.0
# Name: score, dtype: float64

as_indext=False

  • 그룹 라벨이 인덱스로 설정
result = df2.groupby("team", as_index=False)["score"].sum()
result
# team	score
# 0	A  	175
# 1	B 	245
# 2	C 	88

agg()

  • 여러 집계 함수를 한번에 적용
result = df2.groupby("team", as_index=False)["score"].agg(["sum", "mean", "count"])
result
# team	sum	mean	  count
# 0	A	175	87.500000	2
# 1	B 	245	81.666667	3
# 2	C 	88	88.000000	1

  • 그룹별로 여러 컬럼에 다른 집계 함수 적용
df2 = pd.DataFrame({
    'team': ['A', 'A', 'B', 'B', 'B', 'C'],
    'gender': ['M', 'F', 'F', 'M', 'M', 'F'],
    'score': [90, 85, 80, 70, 95, 88],
    "age": [22, 23, 24, 25, 26, 27]
})
df2
# team	gender	score 	age
# 0	A	    M	    90	    22
# 1	A   	F	    85	    23
# 2	B   	F	    80	    24
# 3	B   	M	    70	    25
# 4	B	    M	    95	    26
# 5	C	    F	    88	    27
result = df2.groupby("team").agg({
    "score": "mean",
    "age": "max"
})
result
#       score	    age
# team		
# A	   87.500000	23
# B	   81.666667	26
# C	   88.000000	27

  • 컬럼 이름 설정 가능
df = pd.DataFrame({
'dept': ['HR', 'HR', 'IT', 'IT', 'Sales', 'Sales'],
'gender': ['M', 'F', 'F', 'M', 'F', 'F'],
'salary': [3500, 3200, 4000, 4200, 3000, 3100]
})
df
# dept	    gender	salary
# 0	HR	    M	    3500
# 1	HR	    F	    3200
# 2	IT	    F	    4000
# 3	IT	    M	    4200
# 4	Sales	F	    3000
# 5	Sales	F	    3100
result = df.groupby(["dept", "gender"]).agg(
    count=("salary", "count"),
    total_salary=("salary", "sum")
)
result
#               count	total_salary
# dept	gender		
# HR	  F	      1	    3200
#         M	      1	    3500
# IT	  F	      1	    4000
#         M	      1	    4200
# Sales	  F	      2	    6100

마치며

Pandas 복습보다 더 어려운 것은 코드 결과값을 하나하나 정리하는 일이라는 것을 노션에 정리하고 블로그를 작성하는 지금 가장 크게 느끼고 있다. 행과 열로 이루어진 배열로 결과값이 나오는데, 이를 바로 복사하면 칸이 맞지 않아서 하나하나 수동으로 맞춰줘야 한다. 노션에서 1차 정리를 한 후 블로그에 복사했더니 또다시 칸이 맞지 않아서 처음부터 다시 정리해야 했다. 블로그 글을 작성하는 것보다 수치들의 칸을 맞추는 데 시간이 더 오래 걸린 것 같다.

NOTION

MY NOTION (Pandas. 02)

profile
Hello I'm TaeHyunAn, Currently Studying Data Analysis

0개의 댓글