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

#9 9일차_ multi - level index 실습

ecosso 2026. 5. 21. 12:39

01 multi - level index 실습

 

02 문자열과 정규표현식

 -01 문자열과 정규표현식

 -02 Series와 정규표현식


01 multi - level index 실습

[ 연습문제 ]
교습현황.csv 파일을 읽고데이터를 아래 형태로 변경
                                         2016
                                         1  2   3 ... 12
구       교습과정        교습소명
관악구    보습           바른수학교습소
pd.set_option('display.max_columns', None)

df = pd.read_csv('교습현황.csv', encoding = 'cp949')
df = df.drop(columns = ['분야구분','교습계열'])

df.head()

df.head()
Out[197]: 
         교습소명                                       교습소주소             교습과정  \
0     바른수학교습소            서울특별시 동작구 여의대방로36길 30 , 4층 (대방동)               보습   
1     바른수학교습소            서울특별시 동작구 여의대방로36길 30 , 4층 (대방동)               보습   
2  친니친니중국어교습소  서울특별시 동작구 사당로17길 8 , 113호 (사당동, 대림아파트상가A동)  실용외국어(유아/초·중·고)   
3    성가피아노교습소   서울특별시 동작구 여의대방로 28 현대아파트상가 에이동 402호(신대방동)               음악   
4    성가피아노교습소   서울특별시 동작구 여의대방로 28 현대아파트상가 에이동 402호(신대방동)               음악   

       2016(1)      2016(2)      2016(3)      2016(4)      2016(5)  \
0   6,628,000    1,059,000    3,053,000    6,610,000    5,101,000    
1   1,624,000    6,044,000    6,575,000    6,199,000    4,250,000    
2   6,042,000    6,610,000    1,344,000    1,582,000      906,000    
3   1,729,000    6,697,000    5,960,000    1,549,000    5,979,000    
4   1,650,000    1,049,000    2,296,000      551,000    6,952,000

 

# 문제풀이

# 구 추출/ 주소 컬럼 제거
df['구'] = df['교습소주소'].str[6:9]
df = df.drop(columns = '교습소주소')

# ** 먼저 정렬을 해두는 것이 좋다!
# 구 / 교습과정 / 교습소명 정렬 후 멀티인덱스 생성
df.sort_values(['구','교습과정','교습소명']).set_index(['구','교습과정','교습소명'])

 

# 멀티 컬럼 생성
g1 = df.columns.str[:4]
g2 = df.columns.str[5:7].str.replace(')','')

df.columns = [g1, g2]

# 숫자컬럼 변경
df.applymap(lambda x : x.replace(',','')).astype(int) # 현재버전 가능
df = df.map(lambda x : x.replace(',','')).astype(int) # 이후버전용
df.dtypes

# 교습소별로 연도별 매출 총합
df2 = df.groupby(level=2).sum().T.groupby(level=0).sum().T

# 교습소명 출력
result = df2.idxmax().unique()[0]
print(result)


02 문자열과 정규표현식

# 정규표현식을 도와주는 function이 있다.
# ** 메타문자
\d : 숫자
\D : 숫자를 제외한 
\s : 공백
\S : 공백을 제외한
\w : 숫자, 문자(한글, 영문), _
\W : 숫자, 문자(한글, 영문), _ 를 제외한 모든 글자 => _를 제외한 특수기호 + 공백
[[:digit:]] : 숫자
[[:alpha:]] : 문자(한글,영문)
[[:alnum:]] : 문자, 숫자
[[:punct:]] : 특수기호

^ : 시작
  ex) '^a' : a로 시작하는 
$ : 끝
  ex) 'a$' : a로 끝나는
() : 연산 우선순위 변경 / 그룹을 묶기 위해 사용
  ex) 02-345-2345 => \d+-\d+-\d+
  ex) (\d{2,3})-(\d{3,4})-(\d{4}))
| : 또는
  ex) '^a|b' : a로 시작하거나 b를 포함하는
      '^(a|b)' : a 또는 b로 시작하는
 
\ :  excape character
바로 뒤에 오는 한글자의 메타문자를 일반기호화하기 위해 사용

ex) in sql
where id like 'a_%'   a_123, a1
where id like 'a!_%' escape '!' a_123

. : 한 글자의 모든 글자 지정 (숫자,문자,특수기호,공백)
    sql의 llike 연산자의 _와 같은 의미

[] : 한 글자의 지정된 글자만 허용([] 안의 메타문자는 일반기호처럼 해석(^제외))
  ex) [0-9] [a-zA-Z] = [A-z]
  ex) 031)333-1234, 02-4444-1234 => \d{2,3}(-|/))\d{3,4}-\d{4}

[^] : 지정된 글자를 제외한 모든 글자를 허용하는 한 글자
  ex) '^[^mtws].+day' => monday tuesday ... sunday 중 friday만 선택됨

+ : 1회 이상
* : 0회 이상
? : 0회 또는 1회
{n,m} : n회 이상 m회 이하 반복
{n, } : n회 이상 반복
{n} : n회 반복

ex) where regexp_like('123aaaabcd', '\d+a{2}') -> True
    select regexp_substr('123aaaabcd', '\d+a{2}') -> 123aa
    select regexp_substr('123aaaabcd', '\d+a{2,}') -> 123aaaa


 -01 문자열과 정규표현식
 1) re.findall(pattern, string)

패턴에 만족하는 모든 문자열을 추출한다.

()를 사용하여 서브그룹 선언 시 서브그룹이 추출된다.


 2) re.search(pattern, string)

패턴을 만족하는 문자열을 모두 추출한다.


 3) re.matich(pattern, string)

패턴으로 시작하는지에 대한 여부를 확인한다.

 

import re
dir(re)


 

ex)
str1 = 'abc123 a2222 gg99! df123'
str2 = '031)3455-4556'
str3 = '031-3455-4556'

 

re.findall(r'a\d+', str1)

re.findall(r'a\d+', str1)
Out[304]: ['a2222']

 

re.findall(r'[a-z]+\d+', str1)

re.findall(r'[a-z]+\d+', str1)
Out[297]: ['abc123', 'a2', 'gg99', 'df123']

 

re.findall(r'\d+[-)]\d+-\d+', str2)

re.findall(r'\d+[-)]\d+-\d+', str2)
Out[317]: ['031)3455-4556']


re.findall(r'\d+[-)]\d+-\d+', str3)

re.findall(r'\d+[-)]\d+-\d+', str3)
Out[318]: ['031-3455-4556']

 

re.search(r'a\d+', str1).group()

re.search(r'a\d+', str1).group()
Out[324]: 'a2222'


re.match(r'a\d+', str1)


 -02 Series와 정규표현식 (***)
 1) str.findall
 2) str.search
 3) str.match

 

s1 = pd.Series('abc123 a2222 gg99! df123'.split(' '))
s1.str.match(r'a\d+')

s1.str.match(r'a\d+')
Out[328]: 
0    False
1     True
2    False
3    False
dtype: bool