IT/언어

[python] 머신러닝을 위한 Python(7) ; Data Handling - Pandas # 2

개발자 두더지 2020. 6. 5. 19:33
728x90

1) Groupby 1

(1) Groupby

- SQL groupby 명령어와 같음

- split => apply => combine 과정을 거쳐 연산

df.groupby("묶음의 기준이 되는 컬럼")["적용받는 컬럼"].적용받는연산()
ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
         'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}

df = pd.DataFrame(ipl_data)
print(df)
>> 
      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
2   Devils     2  2014     863
3   Devils     3  2015     673
4    Kings     3  2014     741
5    kings     4  2015     812
6    Kings     1  2016     756
7    Kings     1  2017     788
8   Riders     2  2016     694
9   Royals     4  2014     701
10  Royals     1  2015     804
11  Riders     2  2017     690


# 결과 Team을 기준으로 Points를 Sum
h_index = df.groupby("Team")["Points"].sum()
>>
Team
Devils    1536
Kings     2285
Riders    3049
Royals    1505
kings      812
Name: Points, dtype: int64


# 한 개 이상의 column을 묶을 수 있다.
h_index = df.groupby(["Team", "Year"])["Points"].sum()
print(h_index)
>>
Team    Year
Devils  2014    863
        2015    673
Kings   2014    741
        2016    756
        2017    788
Riders  2014    876
        2015    789
        2016    694
        2017    690
Royals  2014    701
        2015    804
kings   2015    812
Name: Points, dtype: int64

 

(2) Hiearchical index

- Groupby 명령의 결과물도 결국은 dataframe

- 두 개의 column으로 groupby를 할 경우, index가 두 개 생성

h_index.index
>>
MultiIndex([('Devils', 2014),
            ('Devils', 2015),
            ( 'Kings', 2014),
            ( 'Kings', 2016),
            ( 'Kings', 2017),
            ('Riders', 2014),
            ('Riders', 2015),
            ('Riders', 2016),
            ('Riders', 2017),
            ('Royals', 2014),
            ('Royals', 2015),
            ( 'kings', 2015)],
           names=['Team', 'Year'])


h_index["Devils":"Kings"]
>>
       Team    Year
Devils  2014    863
        2015    673
Kings   2014    741
        2016    756
        2017    788
Name: Points, dtype: int64
​

 

(3) Hierarchical index - unstack()

- Group으로 묶여진 데이터를 matrix 형태로 전환해줌

h_index.unstack()
>>
Year     2014   2015   2016   2017
Team
Devils  863.0  673.0    NaN    NaN
Kings   741.0    NaN  756.0  788.0
Riders  876.0  789.0  694.0  690.0
Royals  701.0  804.0    NaN    NaN
kings     NaN  812.0    NaN    NaN

 

(4) Hierarchical index - swaplevel

- Index level을 변경할 수 있음

h_index.swaplevel()
>>
Year  Team  
2014  Devils    863
2015  Devils    673
2014  Kings     741
2016  Kings     756
2017  Kings     788
2014  Riders    876
2015  Riders    789
2016  Riders    694
2017  Riders    690
2014  Royals    701
2015  Royals    804
      kings     812
Name: Points, dtype: int64

# h_index.swaplevel().sortlevel(0)

h_index.swaplevel().sort_index(0)
>> 
Year  Team  
2014  Devils    863
      Kings     741
      Riders    876
      Royals    701
2015  Devils    673
      Riders    789
      Royals    804
      kings     812
2016  Kings     756
      Riders    694
2017  Kings     788
      Riders    690
Name: Points, dtype: int64
강좌 자료의 코드 중
h_index.swaplevel().sortlevel(0)
를 실행한 결과

AttributeError: 'Series' object has no attribute 'sortlevel' 에러가 발생하였다.

검색한 결과 방법 두 가지를 찾았다.
(1안) pandas를 update
using conda: conda update pandas
using pip: pip install pandas -U
> 여전히 동일 오류 발생

(2안) sortlevel(0)대신 sort_index() 사용
pandas.DataFrame.sortlevel()는 pandas 버전 0.20.0부터 사라졌다고 한다.
> 2안 방법을 쓰니 자료와 동일한 결과 출력

 

(5) Hierarchical index - operations

- Index level을 기준으로 기본 연산 수행 가능

h_index.sum(level=0)
>> 
Team
Devils    1536
Kings     2285
Riders    3049
Royals    1505
kings      812
Name: Points, dtype: int64

h_index.sum(level=1)
>> 
Year
2014    3181
2015    3078
2016    1450
2017    1478
Name: Points, dtype: int64

2) Groupby - grouped

- Groupby에 의해 Split된 상태를 추출 가능함

# Tuple형태로 그룹의 key 값 Value값이 추출됨
grouped = df.groupby("Team") # split된 상태로 grouped에 저장됨

for name, group in grouped:
    print(name)
    print(group)
>> 
Devils
     Team  Rank  Year  Points
2  Devils     2  2014     863
3  Devils     3  2015     673
Kings
    Team  Rank  Year  Points
4  Kings     3  2014     741
6  Kings     1  2016     756
7  Kings     1  2017     788

- 특정 key값을 가진 그룹의 정보만 추출 가능

grouped.get_group("Devils")
>>
     Team  Rank  Year  Points
2  Devils     2  2014     863
3  Devils     3  2015     673

- 추출된 group 정보에는 아래의 세 가지 유형의 apply가 가능함

◆ Aggregation : 요약된 통계정보를 추출해 줌

◆ Transformation : 해당 정보를 변환해줌

◆ Filtration : 특정 정보를 제거 하여 보여주는 필터링 기능

 

(1) Groupby - Aggragation

# Aggregation 예제 1
grouped.agg(sum)
>>        Rank  Year  Points
Team
Devils     5  4029    1536
Kings      5  6047    2285
Riders     7  8062    3049
Royals     5  4029    1505
kings      4  2015     812


# Aggregation 예제 2
grouped.agg(np.mean)
>>
             Rank         Year      Points
Team
Devils  2.500000  2014.500000  768.000000
Kings   1.666667  2015.666667  761.666667
Riders  1.750000  2015.500000  762.250000
Royals  2.500000  2014.500000  752.500000
kings   4.000000  2015.000000  812.000000


# Aggregation 예제 3 ; 특정 컬럼에 여러 개의 function을 Apply할 수  있음
grouped['Points'].agg([np.sum, np.mean, np.std])
>>
         sum        mean         std
Team
Devils  1536  768.000000  134.350288
Kings   2285  761.666667   24.006943
Riders  3049  762.250000   88.567771
Royals  1505  752.500000   72.831998
kings    812  812.000000         NaN

 

(2) Groupby - transformation

- Aggregation과 달리 key값 별로 요약된 정보가 아니라 개별 데이터의 변환을 지원함

# transformation 예제 1
score = lambda x: (x)
print(grouped.transform(score))
>>
    Rank  Year  Points
0      1  2014     876
1      2  2015     789
2      2  2014     863
3      3  2015     673
4      3  2014     741
5      4  2015     812
6      1  2016     756
7      1  2017     788
8      2  2016     694
9      4  2014     701
10     1  2015     804
11     2  2017     690


# transformation 예제 2 ; group으로 묶여진 단위를 하나의 Series로 보고 max나 min이 적용됨
score = lambda x: (x.max())
print(grouped.transform(score))
>>
    Rank  Year  Points
0      2  2017     876
1      2  2017     876
2      3  2015     863
3      3  2015     863
4      3  2017     788
5      4  2015     812
6      3  2017     788
7      3  2017     788
8      2  2017     876
9      4  2015     804
10     4  2015     804
11     2  2017     876


# transformation 예제 3 ; 그룹별로 정규분포 적용
score = lambda x: (x- x.mean())/x.std()
print(grouped.transform(score))
>>
        Rank      Year    Points
0  -1.500000 -1.161895  1.284327
1   0.500000 -0.387298  0.302029
2  -0.707107 -0.707107  0.707107
3   0.707107  0.707107 -0.707107
4   1.154701 -1.091089 -0.860862
5        NaN       NaN       NaN
6  -0.577350  0.218218 -0.236043
7  -0.577350  0.872872  1.096905
8   0.500000  0.387298 -0.770596
9   0.707107 -0.707107 -0.707107
10 -0.707107  0.707107  0.707107
11  0.500000  1.161895 -0.815759

 

(3) Groupby - filter

- 특정 조건으로 데이터를 검색할 때 사용

- filter 안에는 boolean 조건이 존재해야함

- len(x)는 grouped된 dataframe 개수

result = df.groupby('Team').filter(lambda x: len(x) >= 3) # 데이터가 3개 이상 있을 경우에만 출력
print(result)
>>
      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
4    Kings     3  2014     741
6    Kings     1  2016     756
7    Kings     1  2017     788
8   Riders     2  2016     694
11  Riders     2  2017     690

3) Pivot table Crosstab

강좌에서 사용한 데이터에 관련된 github는 아래의 주소를 참고

https://github.com/TEAMLAB-Lecture/AI-python-connect/blob/master/codes/ch_3/part-2/data/phone_data.csv

 

(1) Pivot Table

- Excel에서 보던 그것!

- Index축은 groupby와 동일함

- Column에 추가로 labelling 값을 추가하여, Value에 numeric type 값을 arregation 하는 형태

- 참고로 dateutil는 date 데이터를 String이 아닌 date 타입 그대로 가져오는 것

(2) Crosstab

- 특히 두 칼럼에 교차 빈도, 비율 덧셈 등을 구할 때 사용

- Pivot table의 특수한 형태

- User-Item Rating Matrix 등을 만들 때 사용 가능함


4) Merge & Concat

(1) Merge

- SQL에서 많이 사용하는 Merge와 같은 기능 ; 두 개의 데이터를 하나로 합침

# subject_id를 기준으로 merge
pd.merger(df_a, df_b, on = 'subject_id')

# 두 dataframe이 column이름이 다를 때
pd.merge(df_a, df_b, left_on = 'subject_id', right_on = 'subject_id')

 

(2) Join method

# Left Join
pd.merger(df_a, df_b, on = 'subject_id', how='left')

# Right Join
pd.merger(df_a, df_b, on = 'subject_id', how='right')

# Full(outer) Join
pd.merger(df_a, df_b, on = 'subject_id', how='outer')

# Inner Join
pd.merger(df_a, df_b, on = 'subject_id', how='inner')

# Index based join
pd.merger(df_a, df_b, right_index =True , left_index= True)

 

(3) Concat

- 같은 형태의 데이터를 붙이는 연산 작업

# 예 1
df_new = pd.concat([df_a, df_b])
df_new.reset_index()

# 예 2
df_new = pd.concat([df_a, df_b], axis=1)
df_new.reset_index()

5) DB Persistence

(1) Database connection

- Data loading 시 db connection 기능 제공함

(2) XLS persistence

- Dataframe의 엑셀 추출 코드

- XLS 엔진으로 ipenpyxls 또는 XlsxWrite 사용

(3) Pickle persistence

- 가장 일반적인 python 파일 persistence

- to_pickle, read_pickle함수 사용


참고자료

https://www.edwith.org/aipython/lecture/23823/

728x90