데이터셋을 분류하고 각 그룹별로 집계나 변형 같이 어떤 함수를 적용하는 작업은 데이터 분석과정에서 무척 중요한 일이다. 데이터를 불러오고 취합해서 하나의 데이터셋을 준비한 후 그룹 통계를 구하거나 가능하다면 피벗 테이블을 구해 보고서를 만들고 시각화한다. 판다스는 데이터셋을 자연스럽게 나누고 요약하는 groupby라는 유연한 방법을 제공한다.
1. 그룹 연산에 대한 고찰
다수의 인기 있는 R 프로그래밍 패키지 저자인 해들리 위컴은 그룹 연산에 대해 분리-적용-결합(split-apply-combine)이라는 새로운 용어를 만들었다. 그룹 연산의 첫 번째 단계에서는 Series, DataFrame 같은 판다스 객체나 다른 객체에 들어 있는 데이터를 하나 이상의 키 기준으로 분리한다. 객체는 하나의 축을 기준으로 분리되는데 예를 들면 DataFrame은 행(axis="index")이나 열(axis="columns") 기준으로 분리할 수 있다. 분리하고 나면 한수를 각 그룹에 적용시켜 새로운 값을 얻어낸다. 마지막을오 함수를 적용한 결과를 하나의 객체로 결합한다. 결과를 담는 객체는 데이터에 어떤 연산을 했는지에 따라 결정된다.
1) 그룹 간 순회하기
groupby 메서드에서 반환된 객체는 순회(이터레이션)를 지원하는데, 그룹 이름과 그에 따른 데이터 묶음을 튜플로 반환한다.
df = pd.DataFrame({"key1" : ["a", "a", None, "b", "a", None],
"key2: pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),
"data1" : np.random.standard_normal(7),
"data2" : np.random.standard_normal(7)}]
for name, group in df.groupby("key1"):
print(name)
print(group)
2) 열이나 열의 일부만 선택하기
DataFram에서 만든 GroupBy 객체를 열 이름이나 열 이름이 담긴 배열로 색인하면 수집을 위해 해당 열을 선택하게 된다.
특히 대용량 데이터셋을 다룰 때 소수의 열만 집계하고 싶을 경우가 종종 있다 예를 들어 앞의 데이터셋에서 data2 열에 대해서만 평균을 구하고 결과를 DataFrame으로 받고 싶다면 다음과 같이 작성하면 된다.
df.groupby(["key1", "key2"])[["data2"]].mean()
3) 딕셔너리와 Series에서 그룹화 하기
people = pd.DataFrame(np.random.standard_normal((5,5)),
column=["a","b","c","d","e"].
index=["joe","Steve","Wanda","Jill","Trey])
people.iloc[2:3, [1,2]] = np.nan
mapping = {"a" : "red", "b" : "red", "c": "blue", "d": "blue", "e":"red", "f":"orange"}
# 딕셔너리에서 groupby 메서드로 넘길 배열을 뽑을 수 있지만 그냥 이 딕셔너리를 groupby 메서드로 넘긴다.(사용하지 않을 그룹 키 문제도 보
# 여주기 위해 "f"도 포함 됐다
by_column = people.groupby(mapping, axis="columns")
by_column.sum()
# Series에 대해서도 같은 기능을 수행할 수 있는데 고정된 크기의 매핑이라고 보면 된다.
map_series = pd.Series(mapping)
map_series
4) 함수로 그룹화하기
파이썬 함수를 사용하는 방법은 딕셔너리와 Series를 사용해서 그룹을 매핑하는 것보다 조금 더 일반적이다. 그룹 색인으로 넘긴 함수는 색인값 하나마다 한 번씩 호출되며(또는 axis="columns"를 사용한 경우에는 열의 값 하나마다 한 번씩), 반환값은 그 그룹의 이름으로 사용된다.
5) 색인 단계로 그룹화하기
계층적으로 색인된 데이터셋은 축 색인의 단계 중 하나를 사용해서 편리하게 집계할 수 있따.
2. 데이터 집계
1) 열에 여러 가지 함수 적용하기
agg 메서드 사용
2) 색인되지 않은 형태로 집계된 데이터 반환하기
groupby 메서드에 as_index=False를 넘겨서 색인 작업을 비활성화 할 수 있다.
색인된 결과 대해 reset_index 메서드를 호출하면 동일한 결과를 얻을 수 있다.
3. apply 메서드: 일반적인 분리-적용-병합
def top(df, n=5, column="tip_pct"):
return df.sort_values(column, ascending=False)[:n]
# 흡연자(smoker)그룹에 대해 이 함수를 apply 할 수 있다.
tips.groupby("smoker").apply(top)
# 만약 apply메서드에 넘길 함수가 추가적인 인수나 예약어를 받는다면 함수 이름 뒤에 붙여서 넘겨주면 된다.
tips.groupby(["smoker","day"]).apply(top, n =1, column="total_bill")
1) 그룹 키 생략하기
반환된 객체에는 원본 객체의 각 조각에 대한 색인과 그룹 키가 계층적 색인으로 사용됨을 확인할 수 있었다. groupby 메서드에 group_keys=False를 전달하면 이런 결과를 방지할 수 있다.
2) 사분위수 분석과 버킷 분석
- 사분위수: 데이터 표본을 4개의 동일한 부분으로 나눈 값
pandas.cut, pandas.qcut 메서드를 사용해서 선택한 크기만큼 혹은 표본 사분위수에 따라 데이터를 나눌 수 있었다. 이 함수들을 groupby와 조합하면 데이터셋에 대한 사분위수 분석이나 버킷 분석을 매우 쉽게 수행할 수 있다. - 버킷: 히스토그램에서 동일한 크기의 구간을 몇 개로 잡을 것이냐
3) 그룹별 값으로 결측치 채우기
dropna 또는 fillna
4) 랜덤 표본과 순열
sample 메서드 사용
트럼프 덱 생성
suits = ["H","S", "C", "D"] #하트, 스페이드, 클럽, 다이아몬드
card_val = (list(range1,11)) + [10]*3)*4
base_name=["A"] + list(range(2,11)) + ["J", "K", "Q"]
cards = []
for suit in suits:
cards.extend(str(num) + suit for num in base_names)
deck = pd.Sereis(card_val, index=cards)
다섯 장의 카드를 뽑는 함수
def draw(deck, n = 5):
return deck.sample(n)
각 모양별로 두 장의 카드를 무작위로 뽑기 위해 apply 사용
def get_suit(card):
return card[-1]
deck.groupby(get_suit).apply(draw, n=2)
5) 그룹 가중평균과 상관관계
가중평균: 크고 작음이나 많고 적음의 차이가 나지 않게 한 것, 또는 그 러한 차이가 없이 고르게 한 것, 평균 성적 / 평균을 내다
상관관계: 어떤 변수가 증가할 때 다른 변수가 함께 증가하는지, 혹은 감소하는지 관찰해서 파악
6) 그룹별 선형 회귀
선형 회귀는 종속 변수 y와 한 개 이상의 독립 변수 (또는 설명 변수) X와의 선형 상관 관계를 모델링
4. 그룹 변환과 래핑되지 않는 groupby
- transform 메서드는 apply와 유사하지만 다음과 같이 더 많은 제약사항을 가지낟.
- 그룹 모양대로 브로드 캐스팅할 스칼라 값을 생성할 수 있다.
- 입력 그룹과 동일한 모양의 객체를 사용할 수 있다.
- 입력을 변경하면 안된다.
mean이나 sum 같은 내장 집계함수는 종종 일반 apply 함수보다 빠르다. transform과 함께 사용할 대 취할 수 있는 빠른 경로가 존재하며 래핑되지않는 그룹 연산 작업을 수행할수 있도록 만든다.
5. 피벗 테이블과 교차표
피벗 테이블은 스프레드시트 프로그램과 다른 데이터 분석 소프트웨어에서 흔히 볼 수 있는 데이터 요약 도구이다.
1) 교차표
교차표는 드룹 빈도를 계산하는 특수한 피벗 테이블이다.
'IT > Data Analysis with python' 카테고리의 다른 글
시계열_2 (0) | 2024.07.07 |
---|---|
시계열_1 (0) | 2024.07.07 |
그래프와 시각화 (0) | 2024.06.20 |
데이터 준비하기: 조인, 병합, 변형 (0) | 2024.06.17 |
데이터 정제 및 준비 (1) | 2024.06.14 |