아이티윌_데이터 분석 55기/강의내용 필기_Python

#11 11일차_다양햔 replace 형태, long <-> wide 변환

ecosso 2026. 5. 26. 13:13

01 다양햔 replace 형태 

 -01 기본 문자열 메서드

 -02 str.replace (벡터화 내장된 문자열 메서드)

 -03 pandas 호출 가능한 replace(값 치환 메서드)

 

02 long <-> wide 변환

 -01 unstack

 -02 stack

 -03 pd.crosstab

 -04 pd.pivot_table


01 다양햔 replace 형태 

 -01 기본 문자열 메서드
 - 문자 상수 호출 가능한 메서드
 - 정규표현식 전달 불가(무시)
 - 문자열 일부 치환/삭제

 

'abc123'.replace('123','')
'abc123'.replace('\d','')

'abc123'.replace('123','')
Out[8]: 'abc'

'abc123'.replace('\d','')
Out[9]: 'abc123'

 -02 str.replace (벡터화 내장된 문자열 메서드)
 - Series가 호출 가능한 문자열 메서드
 - 문자열 일부 치환/삭제
 - 정규표현식 전달 가능(regex = True로 설정해야 함)
import pandas as pd
from pandas import Series, DataFrame
s1 = Series(['abc123', '12345','aaaaa']) 

s1
Out[111]: 
0    abc123
1     12345
2     aaaaa
dtype: object


s1.str.replace('\d','')                  # 정규표현식 무시됨(숫자 그대로)

s1.str.replace('\d','')                  # 정규표현식 무시됨(숫자 그대로)
Out[112]: 
0    abc123
1     12345
2     aaaaa
dtype: object


s1.str.replace('\d','',regex = True)     # 정규표현식 반영됨(숫자 모두 삭제됨)

s1.str.replace('\d','',regex = True)     # 정규표현식 반영됨(숫자 모두 삭제됨)
Out[113]: 
0      abc
1         
2    aaaaa
dtype: object

 -03 pandas 호출 가능한 replace(값 치환 메서드)
 - Series, DataFrame 호출 가능한 메서드
 - 값 치환 메서드: 일치하는 값들에 대해 치환/삭제 처리
 - 정규표현식 전달 가능(regex = True로 설정해야 함) => 문자열 메서드로 해석됨
import numpy as np
s1.replace('a','')                            # 무시

s1.replace('a','')                            # 무시
Out[115]: 
0    abc123
1     12345
2     aaaaa
dtype: object


s1.replace('abc123', np.nan)                  # abc123값을 NA로 치환

s1.replace('abc123', np.nan)                  # abc123값을 NA로 치환
Out[116]: 
0      NaN
1    12345
2    aaaaa
dtype: object


s1.replace(['abc123','aaaaa'], np.nan)        # 동시 치환 가능

s1.replace(['abc123','aaaaa'], np.nan)        # 동시 치환 가능
Out[117]: 
0      NaN
1    12345
2      NaN
dtype: object


s1.replace('\d', '')                          # 무시

s1.replace('\d', '')                          # 무시
Out[118]: 
0    abc123
1     12345
2     aaaaa
dtype: object


s1.replace('\d', '', regex = True)            # 문자열 일부 치환/삭제 가능(regex = True 설정시)

s1.replace('\d', '', regex = True)            # 문자열 일부 치환/삭제 가능(regex = True 설정시)
Out[119]: 
0      abc
1         
2    aaaaa
dtype: object

 



# 예) card_history.csv 파일을 읽고 천단위 구분기호(,) 삭제 후 숫자처리
card = pd.read_csv('card_history.csv', encoding = 'cp949')

card
Out[122]: 
        식료품       의복     외식비       책값 온라인소액결제     의료비
NUM                                                  
1    19,400  143,000   8,600   29,000   5,600  19,200
2    22,200  120,400   7,000   26,000   3,300  13,000
3    24,600   88,500   7,500   22,000   7,500  16,600
4    22,300  124,800   7,700   78,000   3,900  28,100
5    31,800  130,100   8,400   25,000   7,700  20,500
6    43,000  118,200   6,300   25,000   4,300  32,500
7    29,400  147,600  10,700   24,000  12,000  26,500
8    29,200  161,900   7,500   33,000   6,300   3,500
9    29,100  134,900   4,600   27,000   7,300  18,700
10   24,000  136,100   8,100   32,000   6,600  24,400


card.set_index('NUM', inplace = True)

card.set_index('NUM', inplace = True)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_27200\1681761336.py in ?()
----> 1 card.set_index('NUM', inplace = True)

~\anaconda3\Lib\site-packages\pandas\core\frame.py in ?(self, keys, drop, append, inplace, verify_integrity)
   6140                     if not found:
   6141                         missing.append(col)
   6142 
   6143         if missing:
-> 6144             raise KeyError(f"None of {missing} are in the columns")
   6145 
   6146         if inplace:
   6147             frame = self

KeyError: "None of ['NUM'] are in the columns"



# 1) 기본 문자열 메서드
'19,400'.replace(',','')

'19,400'.replace(',','')
Out[125]: '19400'


card.map(lambda x : x.replace(',','')).astype('int')

card.map(lambda x : x.replace(',','')).astype('int')
Out[126]: 
       식료품      의복    외식비      책값  온라인소액결제    의료비
NUM                                              
1    19400  143000   8600   29000     5600  19200
2    22200  120400   7000   26000     3300  13000
3    24600   88500   7500   22000     7500  16600
4    22300  124800   7700   78000     3900  28100
5    31800  130100   8400   25000     7700  20500
6    43000  118200   6300   25000     4300  32500
7    29400  147600  10700   24000    12000  26500
8    29200  161900   7500   33000     6300   3500
9    29100  134900   4600   27000     7300  18700
10   24000  136100   8100   32000     6600  24400


# 2) str.replace
card.str.replace(',','')                                    # error(DataFrame은 str 호출 불가)

Series만 호출 가능하므로 DataFrame은 'str' 호출이 불가능하다.

따라서 다음과 같은 에러가 발생한다.

card.str.replace(',','')                                    # error(DataFrame은 str 호출 불가)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_27200\1147864219.py in ?()
----> 1 card.str.replace(',','')                                    # error(DataFrame은 str 호출 불가)

~\anaconda3\Lib\site-packages\pandas\core\generic.py in ?(self, name)
   6317             and name not in self._accessors
   6318             and self._info_axis._can_hold_identifiers_and_holds_name(name)
   6319         ):
   6320             return self[name]
-> 6321         return object.__getattribute__(self, name)

AttributeError: 'DataFrame' object has no attribute 'str'


card.apply(lambda x : x.str.replace(',','')).astype('int')  # 정상

card.apply(lambda x : x.str.replace(',','')).astype('int')  # 정상
Out[128]: 
       식료품      의복    외식비      책값  온라인소액결제    의료비
NUM                                              
1    19400  143000   8600   29000     5600  19200
2    22200  120400   7000   26000     3300  13000
3    24600   88500   7500   22000     7500  16600
4    22300  124800   7700   78000     3900  28100
5    31800  130100   8400   25000     7700  20500
6    43000  118200   6300   25000     4300  32500
7    29400  147600  10700   24000    12000  26500
8    29200  161900   7500   33000     6300   3500
9    29100  134900   4600   27000     7300  18700
10   24000  136100   8100   32000     6600  24400


# 3) df.replace
card.replace(',','')                                        # 무시

card.replace(',','')                                        # 무시
Out[129]: 
        식료품       의복     외식비       책값 온라인소액결제     의료비
NUM                                                  
1    19,400  143,000   8,600   29,000   5,600  19,200
2    22,200  120,400   7,000   26,000   3,300  13,000
3    24,600   88,500   7,500   22,000   7,500  16,600
4    22,300  124,800   7,700   78,000   3,900  28,100
5    31,800  130,100   8,400   25,000   7,700  20,500
6    43,000  118,200   6,300   25,000   4,300  32,500
7    29,400  147,600  10,700   24,000  12,000  26,500
8    29,200  161,900   7,500   33,000   6,300   3,500
9    29,100  134,900   4,600   27,000   7,300  18,700
10   24,000  136,100   8,100   32,000   6,600  24,400


card.replace('19,400','')                                   # 완전히 일치하는 값 자체를 치환 기능

'19,400'와 정확하게 일치하는 값 자체를 치환가능하기 때문에 DataFrame 내의 모든 원소가 치환되지 않는다.

card.replace('19,400','')                                   # 완전히 일치하는 값 자체를 치환 기능
Out[130]: 
        식료품       의복     외식비       책값 온라인소액결제     의료비
NUM                                                  
1            143,000   8,600   29,000   5,600  19,200
2    22,200  120,400   7,000   26,000   3,300  13,000
3    24,600   88,500   7,500   22,000   7,500  16,600
4    22,300  124,800   7,700   78,000   3,900  28,100
5    31,800  130,100   8,400   25,000   7,700  20,500
6    43,000  118,200   6,300   25,000   4,300  32,500
7    29,400  147,600  10,700   24,000  12,000  26,500
8    29,200  161,900   7,500   33,000   6,300   3,500
9    29,100  134,900   4,600   27,000   7,300  18,700
10   24,000  136,100   8,100   32,000   6,600  24,400


card.replace(',','',regex = True).astype('int')             # 정상

card.replace(',','',regex = True).astype('int')             # 정상
Out[131]: 
       식료품      의복    외식비      책값  온라인소액결제    의료비
NUM                                              
1    19400  143000   8600   29000     5600  19200
2    22200  120400   7000   26000     3300  13000
3    24600   88500   7500   22000     7500  16600
4    22300  124800   7700   78000     3900  28100
5    31800  130100   8400   25000     7700  20500
6    43000  118200   6300   25000     4300  32500
7    29400  147600  10700   24000    12000  26500
8    29200  161900   7500   33000     6300   3500
9    29100  134900   4600   27000     7300  18700
10   24000  136100   8100   32000     6600  24400

# [ 연습문제 ]
# oracle_alert_testdb.log 파일을 읽고
df = pd.read_csv('oracle_alert_testdb.log', sep='|', header=None) 

df
Out[133]: 
                                                       0
0                               Tue Oct 30 17:43:46 2012
1                      Starting ORACLE instance (normal)
2                                LICENSE_MAX_SESSION = 0
3                           LICENSE_SESSIONS_WARNING = 0
4      Shared memory segment for instance monitoring ...
                                                 ...
66281  ORA-00312: online log 2 thread 1: '/data/temp4...
66282  ORA-00312: online log 2 thread 1: '/data/temp4...
66283                           Sun Nov 23 10:30:44 2014
66284  Errors in file /app/oracle/diag/rdbms/testdb/t...
66285           ORA-25153: Temporary Tablespace is Empty

[66286 rows x 1 columns]


# 주요 에러코드 및 에러내용
# ORA-1109 signalled during: ALTER DATABASE CLOSE NORMAL...
# ORA-00313: open failed for members of log group 1 of thread 1

# 1. 에러코드와 에러내용을 아래 데이터프레임 형식으로 저장

# code                        error
# 01109    signalled during: ALTER DATABASE CLOSE NORMAL...
# 00313    open failed for members of log group 1 of thread 1

df = df[0].str.extract(r'ORA-(\d+):? (.+)').dropna()

df
Out[135]: 
           0                                                  1
126     1109   signalled during: ALTER DATABASE CLOSE NORMAL...
252    00313  open failed for members of log group 1 of thre...
253    00312  online log 1 thread 1: '/app/oracle/oradata/te...
254    27037                       unable to obtain file status
260    00313  open failed for members of log group 1 of thre...
     ...                                                ...
66277  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66280  16014  log 2 sequence# 14 not archived, no available ...
66281  00312  online log 2 thread 1: '/data/temp4/redo02_a.log'
66282  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66285  25153                      Temporary Tablespace is Empty

[9812 rows x 2 columns]


df.columns = ['code','error']

df
Out[137]: 
        code                                              error
126     1109   signalled during: ALTER DATABASE CLOSE NORMAL...
252    00313  open failed for members of log group 1 of thre...
253    00312  online log 1 thread 1: '/app/oracle/oradata/te...
254    27037                       unable to obtain file status
260    00313  open failed for members of log group 1 of thre...
     ...                                                ...
66277  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66280  16014  log 2 sequence# 14 not archived, no available ...
66281  00312  online log 2 thread 1: '/data/temp4/redo02_a.log'
66282  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66285  25153                      Temporary Tablespace is Empty

[9812 rows x 2 columns]


df['code'] = df['code'].str.zfill(5)

df
Out[139]: 
        code                                              error
126    01109   signalled during: ALTER DATABASE CLOSE NORMAL...
252    00313  open failed for members of log group 1 of thre...
253    00312  online log 1 thread 1: '/app/oracle/oradata/te...
254    27037                       unable to obtain file status
260    00313  open failed for members of log group 1 of thre...
     ...                                                ...
66277  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66280  16014  log 2 sequence# 14 not archived, no available ...
66281  00312  online log 2 thread 1: '/data/temp4/redo02_a.log'
66282  00312  online log 2 thread 1: '/data/temp4/redo02_b.log'
66285  25153                      Temporary Tablespace is Empty

[9812 rows x 2 columns]


# 2. 가장 많이 출력되는 오라 코드 출력(숫자 5자리)
result = df['code'].mode().iloc[0]

result
Out[141]: '00312'


result = df['code'].value_counts().idxmax()

Out[143]: '00312'

 

02 long <-> wide 변환

 

in SQL) 

long -> wide : pivot value값 for unstack컬럼 in (값1, 값2, ...)

wide -> long : unpivot for in (컬럼1, 컬럼2, ..)

 

in R)

long -> wide : reshape2::decast

wide -> long : reshape2::melt

 

in Python)

long -> wide : df.unstack()

wide -> long : df.stack()

 

파이썬은 멀티인덱스들간의 조정, 즉, 인덱스의 하위레벨이 펼쳐지는 느낌이 있다.

sql과 r이 컬럼 중심이면 파이썬은 인덱스 중심의 느낌이다.

 

 

 -01 unstack
import pandas as pd
emp = pd.read_csv('emp.csv')

emp.untack(level = -1,          # unstack 할 level 지정(default : 가장 최하위 레벨 선택)
           fill_value = np.nan) # 자리를 채울값

emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack()

emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack()
Out[5]: 
DEPTNO         10      20      30
JOB                              
ANALYST       NaN  6000.0     NaN
CLERK      1300.0  1900.0   950.0
MANAGER    2450.0  2975.0  2850.0
PRESIDENT  5000.0     NaN     NaN
SALESMAN      NaN     NaN  5600.0


emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack(fill_value = 0)

emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack(fill_value = 0)
Out[6]: 
DEPTNO       10    20    30
JOB                        
ANALYST       0  6000     0
CLERK      1300  1900   950
MANAGER    2450  2975  2850
PRESIDENT  5000     0     0
SALESMAN      0     0  5600


emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack(level = 0)

emp.groupby(['JOB','DEPTNO'])['SAL'].sum().unstack(level = 0)
Out[7]: 
JOB     ANALYST   CLERK  MANAGER  PRESIDENT  SALESMAN
DEPTNO                                               
10          NaN  1300.0   2450.0     5000.0       NaN
20       6000.0  1900.0   2975.0        NaN       NaN
30          NaN   950.0   2850.0        NaN    5600.0

 

# ex)
df1 = pd.read_csv('melt_ex.csv')
df1.head()

df1
Out[152]: 
    year  mon  latte  americano  mocha
0   2000    1    400        482    298
1   2000    2    401        483    299
2   2000    3    402        484    300
3   2000    4    403        485    301
4   2000    5    404        486    302
5   2000    6    405        487    303
6   2000    7    406        488    304
7   2000    8    407        489    305
8   2000    9    408        490    306
9   2000   10    409        491    307
10  2000   11    410        492    308


df1.set_index(['year','mon']).unstack()     # unstack은 요약기능이 없음

df1.set_index(['year','mon']).unstack()                 # unstack은 요약기능이 없음
Out[153]: 
     latte                                                        americano  \
mon     1    2    3    4    5    6    7    8    9    10   11   12        1    
year                                                                          
2000   400  401  402  403  404  405  406  407  408  409  410  411       482   
2001   412  413  414  415  416  417  418  419  420  421  422  423       494   

                                                            mocha            \
mon    2    3    4    5    6    7    8    9    10   11   12    1    2    3    
year                                                                          
2000  483  484  485  486  487  488  489  490  491  492  493   298  299  300   
2001  495  496  497  498  499  500  501  502  503  504  505   310  311  312   

                                                   
mon    4    5    6    7    8    9    10   11   12  
year                                               
2000  301  302  303  304  305  306  307  308  309  
2001  313  314  315  316  317  318  319  320  321


df1.set_index(['year','mon']).sum(axis=1).unstack()     # 먼저 요약후(판매량 총합) 교차표 생성

df1.set_index(['year','mon']).sum(axis=1).unstack()     # 먼저 요약후(판매량 총합) 교차표 생성
Out[154]: 
mon     1     2     3     4     5     6     7     8     9     10    11    12
year                                                                        
2000  1180  1183  1186  1189  1192  1195  1198  1201  1204  1207  1210  1213
2001  1216  1219  1222  1225  1228  1231  1234  1237  1240  1243  1246  1249

 -02 stack
df1.stack(level = -1,
          dropna = True)
df1

df1
Out[156]: 
          latte  americano  mocha
year mon                         
2000 1      400        482    298
     2      401        483    299
     3      402        484    300
     4      403        485    301
     5      404        486    302
     6      405        487    303
     7      406        488    304
     8      407        489    305
     9      408        490    306
     10     409        491    307
     11     410        492    308
     12     411        493    309
2001 1      412        494    310


df1 = df1.set_index(['year','mon'])

df1 = df1.set_index(['year','mon'])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_27200\3114356990.py in ?()
----> 1 df1 = df1.set_index(['year','mon'])

~\anaconda3\Lib\site-packages\pandas\core\frame.py in ?(self, keys, drop, append, inplace, verify_integrity)
   6140                     if not found:
   6141                         missing.append(col)
   6142 
   6143         if missing:
-> 6144             raise KeyError(f"None of {missing} are in the columns")
   6145 
   6146         if inplace:
   6147             frame = self

KeyError: "None of ['year', 'mon'] are in the columns"


df1.stack().reset_index()

df1.stack().reset_index()                        # 기존 컬럼들이 index의 최하위 level로 배치됨
Out[158]: 
    year  mon    level_2    0
0   2000    1      latte  400
1   2000    1  americano  482
2   2000    1      mocha  298
3   2000    2      latte  401
4   2000    2  americano  483
..   ...  ...        ...  ...
67  2001   11  americano  504
68  2001   11      mocha  320
69  2001   12      latte  423
70  2001   12  americano  505
71  2001   12      mocha  321

[72 rows x 4 columns]

 -03 pd.crosstab
pd.crosstabl(index,             # index 배치 대상
             columns,           # columns 배치 대상
             values=None,       # 교차표에 표현할 대상
             aggfun=None,       # 요약함수
             margins : 'bool' = False,  # 마진 출력 여부
             margins_name : 'Hashable' = 'All', # 마진 이름
             dropna : True)     # NA 제거 여부

ex) emp에서 job, deptno별 sal 총합 교차표 출력
pd.crosstab(emp['JOB'], emp['DEPTNO'])          # 독립성 검정 시 필요한 교차표 형태 (도수)

pd.crosstab(emp['JOB'], emp['DEPTNO'])                                # 독립성 검정 시 필요한 교차표 형태(교차빈도)
Out[159]: 
DEPTNO     10  20  30
JOB                  
ANALYST     0   2   0
CLERK       1   2   1
MANAGER     1   1   1
PRESIDENT   1   0   0
SALESMAN    0   0   4


pd.crosstab(emp['JOB'], emp['DEPTNO'], emp['SAL'], aggfunc = 'sum') # 급여 총합에 대한 교차표

pd.crosstab(emp['JOB'], emp['DEPTNO'], emp['SAL'], aggfunc='sum')     # 급여 총합에 대한 교차표 
Out[160]: 
DEPTNO         10      20      30
JOB                              
ANALYST       NaN  6000.0     NaN
CLERK      1300.0  1900.0   950.0
MANAGER    2450.0  2975.0  2850.0
PRESIDENT  5000.0     NaN     NaN
SALESMAN      NaN     NaN  5600.0


무조건 독립적이다/ 독립적이지 않다라고 말하는 것이 아니라 독립성 검정 결과 ~ 하였다. 라고 말해야 한다.


 -04 pd.pivot_table
emp.pivot_table(values=None,
                index=None,
                columns=None,
                aggfunc='mean',
                fill_value=None,
                margins: 'bool' = False,
                dropna: 'bool' = True,
                margins_name= 'All')

# ex) emp에서 job, deptno별 sal 총합 교차표 출력
emp.pivot_table(index='DEPTNO', columns='JOB', values = 'SAL')      # 평균 리턴

emp.pivot_table(index='DEPTNO', columns = 'JOB', values='SAL')                    # 평균 리턴
Out[161]: 
JOB     ANALYST   CLERK  MANAGER  PRESIDENT  SALESMAN
DEPTNO                                               
10          NaN  1300.0   2450.0     5000.0       NaN
20       3000.0   950.0   2975.0        NaN       NaN
30          NaN   950.0   2850.0        NaN    1400.0


emp.pivot_table(index='DEPTNO', columns='JOB', values = 'SAL', aggfunc = 'sum')     # 총합 리턴

emp.pivot_table(index='DEPTNO', columns = 'JOB', values='SAL', aggfunc = 'sum')   # 총합 리턴
Out[162]: 
JOB     ANALYST   CLERK  MANAGER  PRESIDENT  SALESMAN
DEPTNO                                               
10          NaN  1300.0   2450.0     5000.0       NaN
20       6000.0  1900.0   2975.0        NaN       NaN
30          NaN   950.0   2850.0        NaN    5600.0


# ex) student.csv 파일을 읽고 성별(남자, 여자) 학년별 키 평균을 갖는 교차표 출력
pd.set_option('display.max_columns', None)
std = pd.read_csv('student.csv', encoding = 'cp949')
std

std
Out[165]: 
    STUDNO NAME          ID  GRADE          JUMIN             BIRTHDAY  \
0     9411  이진욱      75true      4  7510231901810  1975/10/23 00:00:00   
1     9412  서재수      pooh94      4  7502241128467  1975/02/24 00:00:00   
2     9413  이미경    angel000      4  7506152123648  1975/06/15 00:00:00   
3     9414  김재수    gunmandu      4  7512251063421  1975/12/25 00:00:00   
4     9415  박동호     pincle1      4  7503031639826  1975/03/03 00:00:00   
5     9511  김신영       bingo      3  7601232186327  1976/01/23 00:00:00   
6     9512  신은경      jjang1      3  7604122298371  1976/04/12 00:00:00   
7     9513  오나라       nara5      3  7609112118379  1976/09/11 00:00:00   
8     9514  구유미      guyume      3  7601202378641  1976/01/20 00:00:00   
9     9515  임세현      shyun1      3  7610122196482  1976/10/12 00:00:00   
10    9611  일지매    onejimae      2  7711291186223  1977/11/29 00:00:00   
11    9612  김진욱    samjang7      2  7704021358674  1977/04/02 00:00:00   
12    9613  안광훈     nonnon1      2  7709131276431  1977/09/13 00:00:00   
13    9614  김문호       munho      2  7702261196365  1977/02/26 00:00:00   
14    9615  노정호     star123      2  7712141254963  1977/12/14 00:00:00   
15    9711  이윤나  prettygirl      1  7808192157498  1978/08/19 00:00:00   
16    9712  안은수    silverwt      1  7801051776346  1978/01/05 00:00:00   
17    9713  인영민    youngmin      1  7808091786954  1978/08/09 00:00:00   
18    9714  김주현       kimjh      1  7803241981987  1978/03/24 00:00:00   
19    9715   허우   wooya2702      1  7802232116780  1978/02/23 00:00:00   

             TEL  HEIGHT  WEIGHT  DEPTNO1  DEPTNO2  PROFNO  
0   055)381-2158     180      72      101    201.0  1001.0  
1   051)426-1700     172      64      102      NaN  2001.0  
2   053)266-8947     168      52      103    203.0  3002.0  
3   02)6255-9875     177      83      201      NaN  4001.0  
4   031)740-6388     182      70      202      NaN  4003.0  
5   055)333-6328     164      48      101      NaN  1002.0  
6   051)418-9627     161      42      102    201.0  2002.0  
7   051)724-9618     177      55      202      NaN  4003.0  
8   055)296-3784     160      58      301    101.0  4007.0  
9    02)312-9838     171      54      201      NaN  4001.0  
10  02)6788-4861     182      72      101      NaN  1002.0  
11  055)488-2998     171      70      102      NaN  2001.0  
12  053)736-4981     175      82      201      NaN  4002.0  
13  02)6175-3945     166      51      201      NaN  4003.0  
14  051)785-6984     184      62      301      NaN  4007.0  
15  055)278-3649     162      48      101      NaN     NaN  
16   02)381-5440     175      63      201      NaN     NaN  
17  031)345-5677     173      69      201      NaN     NaN  
18  055)423-9870     179      81      102      NaN     NaN  
19  02)6122-2345     163      51      103      NaN     NaN


# 성별 컬럼 생성)
# 1) 딕셔너리를 사용한 매핑
std['JUMIN'].astype('str').str[6].replace({'1':'남자','2':'여자'})

std['JUMIN'].astype('str').str[6].map({'1':'남자','2':'여자'})
Out[166]: 
0     남자
1     남자
2     여자
3     남자
4     남자
5     여자
6     여자
7     여자
8     여자
9     여자
10    남자


# 2) np.where
import numpy as np
std['성별'] = np.where(std['JUMIN'].astype('str').str[6] == '1','남자','여자')
▲ 위와 같은 결과


# 3) map + lambda
std['JUMIN'].map(lambda x : '남자' if str(x)[6] == '1' else '여자')
▲ 위와 같은 결과


# 교차표 작성)
std.pivot_table('HEIGHT', '성별', 'GRADE').fillna(0)

std.pivot_table('HEIGHT', '성별', 'GRADE').fillna(0)
Out[170]: 
GRADE           1      2      3       4
성별                                     
남자     175.666667  175.6    0.0  177.75
여자     162.500000    0.0  166.6  168.00


std.pivot_table('HEIGHT', '성별', 'GRADE', fill_value=0)

std.pivot_table('HEIGHT', '성별', 'GRADE', fill_value=0)
Out[171]: 
GRADE           1      2      3       4
성별                                     
남자     175.666667  175.6    0.0  177.75
여자     162.500000    0.0  166.6  168.00