본문 바로가기

Study/class note

python / 문자열(슬라이싱, 스텝,+,*, in, len,isalpha,isdigit)

커피 키오스크 프로그램은 커피 키오스크의 데이터를 오라클 데이터 베이스에 저장되게끔 파이썬과 오라클 연동하는 것을 구현하고 나서 커피 키오스크 클래스에 인공지능 함수를 추가해서 메뉴 추천하는 알고리즘을 입히는 것까지 할 예정.

 

 

077 문자열에서 홀수번째 문자만 추출하기

주어진 문자열에서 홀수번째 문자만 추출하는 방법은 슬라이싱의 스텝을 이용하면 됨.

# 슬라이싱 문법 : 문자열[시작자리: 끝자리: 스텝]

text = 'abcdefghijklmnopqrstu'

print(text[0: :2])    # 0번째부터 끝까지 2칸씩 건너뛰어서 출력

문제289. 아래의 text 변수에서 짝수번째 데이터만 가져오시오.

text = 'abcdefghijklmnopqrstu'

print(text[1: :2])

 

ㅁ 자카드 유사도 알고리즘

    텍스트 분석할 때 유용

ㅇ 머신러닝의 종류 3가지 :

1. 지도학습 : 정답이 있는 데이터로 기계를 학습 시키는 것

2. 비지도 학습 : 정답이 없는 데이터로 기계학습 시키는 것

3. 강화학습 : 기계가 스스로 자기가 속한 환경을 배워나가는 학습 방법

 

ex) 환자의 초음파 사진만보고 이 환자의 용종이 양성인지 음성이지를 바로 인공지능이 보고 판단할 수 있도록 하는 것

= > 이때 사용하는 방법이 거리계산 방법

 

ㅇ 군집간의 거리를 구하는 방법 2가지

1. 연속형 변수 거리(숫자로 된 데이터)

    - 수학적 거리 : 유클리드 거리, 맨하튼 거리, 민코프스키 거리

    - 통계적 거리 : 표준화, 마할라노비스

2. 명목형 변수 거리(문자로 된 데이터)

    - 단순일치 계수

    - 자카드 유사도 계수 : 자카드 유사도 계수값은 0 ~ 1 사이의 값으로 두 집합이 동일하면 1, 공통의 원소가 하나도 없으면 0

 

예제. 아래 두 문자의 자카드 유사도를 구하시오.

(2개의 명목현 변수 a와 b가 얼마나 유사한지를 측정)

a = 'france'

b = 'french'

 

일단, a 변수를 ['FR','RA','AN','NC','CE'] 처럼 리스트에 담아야함. b변수도 ['FR','RE','EN','NC','CH']로 리스트에 담음.

 

a = 'france'
for i in range(len(a) -1):
    print(a[i:i+2].upper())
    
b = 'french'
for i in range(len(b)-1):
    print(b[i:i+2].upper())

 

 

문제290. 출력한 결과를 리스트에 담으시오.

a = 'france'
result1 = []
for i in range(len(a) -1):
    result1.append(a[i:i+2].upper())
    
result

문제291. 이번에는 아래의 b문자열 변수의 내용을 result2라는 아래의 리스트에 담으시오.

b = 'french'
result2 = []
for i in range(len(b)-1):
    result2.append(b[i:i+2].upper())
    
result2

result1 = ['FR','RA','AN','NC','CE'] 

result2 = ['FR','RE','EN','NC','CH']

 

result1 과 result2의 자카드 지수(계수)는 어떻게 되는가?

문제292. 두 집합의 교집합의 갯수를 구하시오.   2개

result1 = ['FR','RA','AN','NC','CE']

result2 = ['FR','RE','EN','NC','CH']

result1 = ['FR','RA','AN','NC','CE']
result2 = ['FR','RE','EN','NC','CH']

cnt = 0
for i in result1:
    if i in result2:
        cnt += 1
print(cnt)

문제293. 두 집합의 합집합의 갯수 구하시오

result1 = ['FR','RA','AN','NC','CE']

result2 = ['FR','RE','EN','NC','CH']

union = set(result1+result2)
print(len(union))

문제294. 문자열을 문자2개씩 쪼개는 함수를 만드시오.

def str_split():
    text = input('문자를 입력하세요 ~')
    result = []
    for i in range(len(text)-1):
        result.append(text[i:i+2].upper())
    return result

문제295. 아래의 jacard라는 함수를 생성하시오.

jacard()

 문자를 입력하세요 ~ france

 문자를 입력하세요 ~ french

 

2   <- 교집합의 갯수

def jacard():
    a = input('문자를 입력하세요 ~')
    b = input('문자를 입력하세요 ~')
    a_rst = []
    b_rst = []
    for i in range(len(a)-1):
        a_rst.append(a[i:i+2].upper())
    for i in range(len(b)-1):
        b_rst.append(b[i:i+2].upper())
    
    cnt = 0
    for i in a_rst:
        if i in b_rst:
            cnt+= 1
    return cnt
    
# 위의 str_split 함수를 활용했을 때
def jacard():
    a = str_split()
    b = str_split()
    cnt = 0
    for i in a:
        if i in b:
            cnt += 1
    return cnt

문제296. 명목형 변수의 유사도를 구하는 자카드 계수 함수를 다음과 같이 구하시오.

jacard()

문자를 입력하세요~ france

문자를 입력하세요~ french

0.25

def jacard():
    a = str_split()
    b = str_split()
    cnt = 0
    for i in a:
        if i in b:
            cnt += 1
    union = set(a+b)
    
    return cnt/len(union)

 

 

078 문자열을 거꾸로 만들기

슬라이싱을 이용하면 매우 간단하게 거꾸로된 문자열을 얻을 수 있음.

문자열 text를 처음부터 끝까지 스텝 -1로 슬라이싱 하면 됨.

text = 'abcdefghijklmnopqrstu'

print(text[: : -1])

문제297. emp2.csv를 판다스로 로드하고 이름을 출력하고 그 옆에 이름을 거꾸로 출력하시오.

import pandas as pd

emp = pd.read_csv("c:\\data\\emp2.csv")

emp['reverse_ename'] = emp['ename'].apply(lambda x:x[::-1])
emp[['ename','reverse_ename']]

 


079 두 개의 문자열 합치기(+)

두 개의 문자열을 합치는 방법은 다음과 같음.

문자열1 + 문자열2 + 문자열3 으로 연산자 +를 이용하면 됨.

a = 'scott'
b = 'king'
print(a+b)

문제 298. 아래의 SQL을 판다스로 구현하시오.

-- SQL
select ename||'의 직업은 '||job||'입니다.'
 from emp;
# 판다스
emp['ename'] + '의 직업은 ' + emp['job'] + '입니다.'

 

 

080 문자열을 반복해서 새로운 문자열로 만들기(*)

print('='*10)     # ==========

문제299. (알고리즘 문제) 아래와 같이 사각형이 출력되게 하시오.

가로의 숫자를 입력하세요~ 3

세로의 숫자를 입력하세요~ 4

★★★
★★★
★★★
★★★

a = int(input('가로의 숫자를 입력하세요~ '))
b = int(input('세로의 숫자를 입력하세요~ '))

for i in range(1,b+1):
    print('★'*a)

 


081 문자열에서 특정 문자가 있는지 확인하기(in)

ex) 보험회사에서 보험 상담원분들이 상담할때 상담 내용중에 혹시 부적절한 용어가 있는지 없는지 확인함. (예: 한달 > 30일) 이를 확인해서 금융감독원에 보고를 해야함. 이 확인 작업을 사람이 하려면 많은 인력과 시간이 듦.

파이썬으로 이 작업을 쉽게 프로그래밍 할 수 있음.

 

보험상담원 상담내용 --> 텍스트로 변경 -->  텍스트에서 특정 단어를 검색

 

예제. 텍스트에서 특정 단어 있는지 확인

txt = 'abcdefghijklmnop'

if 'b' in txt:
    print('존재합니다.')
else:
    print('존재하지 않습니다.')

문제300. 아래의 SQL을 판다스로 구현하시오.

-- SQL
select ename
 from emp
 where ename like '%S%';
# 판다스
emp[['ename']][emp['ename'].apply(lambda x: 'S' in x)]

	# 또는
emp[['ename']][emp['ename'].str.contains('S')]

 

문제301.(점심시간 문제) 이름에 'T'를 포함하고 있는 사원의 이름, 월급, 부서위치를 출력하시오.

import pandas as pd

emp=pd.read_csv("c:\\data\\emp2.csv")
dept=pd.read_csv("c:\\data\\dept3.csv")
result = pd.merge(emp,dept, on = 'deptno')

result[['ename','sal','loc']][result['ename'].apply(lambda x: 'T' in x)]
	# 또는
result[['ename','sal','loc']][result['ename'].str.contains('T')]

 

 

082 문자열에서 특정 문자열이 있는지 확인하기(in)

txt = 'I never graduated from college'

if 'from' in txt:
    print('존재합니다.')
else:
    print('존재하지 않습니다.')

예제1. 스티브 잡스 연설문에서 mother가 몇 번 나오는지 확인하시오.

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().replace('\n',' ').split(' ') # read() 함수로 문자로 변경, replace()로 특정문자 변경
                                                #특정문자를 기준으로 분리하는 함수 split()
jobs3 = []
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))   # 특정 문자를 자르는 함수 strip()

cnt = 0
for i in jobs3:
    if 'mother' in i.lower():
        cnt += 1
print(cnt)

예제2. 스티브 잡스 연설문에서 mother, should가 몇 번 나오는지 출력하시오.

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().replace('\n',' ').split(' ')
                                                
jobs3 = []
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-')) 

cnt = 0
for i in jobs3:
    if i.lower() in ['mother', 'should']:
        cnt += 1
        
print(cnt)

문제302. 위의 코드를 수정해서 아래와 같이 결과가 출력되게 하시오.

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().replace('\n',' ').split(' ') 
                                               
jobs3 = []
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-')) 

m_cnt = 0
s_cnt = 0
for i in jobs3:
    if i.lower() == 'mother':
        m_cnt += 1
    elif i.lower() == 'should':
        s_cnt += 1
        
print('mother %d \nshould %d'%(m_cnt,s_cnt))

	# 또는
    
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))

cnt1=jobs3.count('mother')
cnt2=jobs3.count('should')

print('mother: %d' %cnt1)
print('should: %d' %cnt2)

문제303. mydata3.txt를 내려받고 이 text에서 인공지능이라는 단어가 몇 번 나오는지 count하시오.

news = open("c:\\data\\mydata3.txt",encoding='utf8')
news2 = news.read()
news2.count('인공지능')
	# 또는
news = open("c:\\data\\mydata3.txt",encoding='utf8')
news2 = news.read().replace('\n',' ').split(' ')

news3 =[]
for i in news2:
    news3.append(i.strip('"').strip(',.:;!?-'))

cnt =0
for i in news3:
    if '인공지능' in i:
        cnt+=1
    
print(cnt)

리스트에서 .count('인공지능')를 하는 것은 정확하게 단어가 일치해야지만 카운트 됨. 하지만 문자열에서 .count('인공지능')를 하면 '인공지능'이란 단어를 모두 다 세는 것으로 모든 단어를 찾을 수 있음.

 

 

083 문자열 길이 구하기(len)

a = 'scott'
print(len(a))   # 5
# 문자열 철자의 갯수를 세는 것

b = [1,2,3,4,5]
print(len(b))   
# 리스트의 요소의 갯수를 세는 것

문제304. 이름, 이름 철자의 갯수를 출력하시오.

# 파생변수 만들어서 하는 방법
import pandas as pd
emp = pd.read_csv("c:\\data\\emp2.csv")

emp['ename_len'] = emp['ename'].apply(lambda x:len(x))
emp[['ename','ename_len']]

# 파생변수 x
pd.concat([emp.ename,emp.ename.apply(lambda x:len(x))], axis=1)
	# pd.concat()은 두개의 시리즈를 서로 연결해서 출력하는 함수인데
    # axis=1을 써주면 축으로 연결해서 양 옆으로 붙어서 출력됨.

 

 

084 문자열이 알파벳인지 검사하기(isalpha)

문자열은 문자나 숫자, 기호들로 구성이 됩니다. 코드를 작성하다 보면 특정 문자열이 한글이나 알파벳과 같이 사람의 언어를 표현하기 위해 사용되는 문자로만 구성되어 있는지 확인해야하는 경우가 있음.

파이썬 문자열 객체가 제공하는 메소드인 isalpha()는 주어진 문자열이 사람의 언어 문자로만 구성되어 있는지 확인해줌.

txt1 = 'abcdefg'
txt2 = '가나다라'
txt3 = 'abcd efg'
txt4 = 'abc3de'

print(txt1.isalpha())  # True
print(txt2.isalpha())  #True
print(txt3.isalpha())  #False : 공백
print(txt4.isalpha())  #True : 숫자

문제304. 스티브 잡스 연설문에는 알파벳이 총 몇개 있는지 출력하시오.

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().lower().replace('\n',' ').split(' ')

jobs3=[]
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))

cnt = 0
for i in jobs3:
    for k in i:
        if k.isalpha() == True:
            cnt += 1
print(cnt)      #9255

문제306. 자카드 계수를 구할때 문자만을 이용해야함. 영문자로 된 쌍만 유효하고, 기타 공백이나 숫자, 특수문자가 들어있는 경우에는 그 글자의 쌍을 버려야함. 예를들어 ab+가 입력으로 들어오면 ab만 원소로 남고 b+는 버려야함.

isalpha()를 이용해 코드를 수정.

def str_split():
    text = input('문자를 입력하세요 ~')
    result = []
    for i in range(len(text)-1):
        if text[i:i+2].upper().isalpha() == True:
            result.append(text[i:i+2].upper())
    return result
    
# def jacard():
#     a = str_split()
#     b = str_split()
#     cnt = 0
#     for i in a:
#         if i in b:
#             cnt += 1
#     union = set(a+b)
    
#     return cnt/len(union)

 

 

085 문자열이 숫자인지 검사하기(isdigit)

문자열이 객체의 isdigit() 메소드는 문자열을 구성하는 요소가 모두 숫자인지 체크하고 True 또는 False를 리턴함.

문자열 함수 설명
isalpha() 알파벳(한글)이 맞는지 확인
isdigit() 숫자가 맞는지 확인
isspace() 공백이 맞는지 확인

예제. 아래의 리스트에서 숫자들을 출력하시오.

c = [1,2,4,'a',6,7,'b',2,'e',5,2,'k']

for i in c:
    if str(i).isdigit() == True:
        print(i)

문제307. 스티브 잡스 연설문에 포함된 숫자들을 출력하시오.

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().lower().replace('\n',' ').split(' ')
jobs3 = []

for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))
    
for i in jobs3:
    if i.isdigit() == True:
        print(i)

문제308. 위의 결과는 jobs'2005와 같은 데이터는 출력시키지 않음. 숫자도 출력이 되어지지만 숫자가 포함되어져 있으면 무조건 출력되게 하시오.

import re  # 데이터 정제 전문인 re를 임폴트하고

jobs = open("c:\\data\\jobs.txt", encoding = 'utf8')
jobs2 = jobs.read().lower().replace('\n',' ').split(' ')
jobs3 = []

for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))
    
for i in jobs3:
    if re.search('\d',i):     #i변수에 있는 문자에서 숫자(\d)가 있으면 출력
        print(i)
        
        # 또는
        
for i in jobs2:
    jobs3.append(i.strip('"').strip(',.:;!?-'))
    
for i in jobs3:
    for k in i:
        if k.isdigit() == True:
            print(i)
            break

 

ㅇ 자카드 유사도 함수를 좀 더 완벽하게 만들기 위한 설명

 

case1. 아래의 2개의 집합이 있을때 이 두 집합의 합집합과 교집합을 구하시오.

A = { 1,2,3 }

B = { 2,3,4 }

A∪B = { 1,2,3,4 }

A∩B = { 2,3 }

 

result1 = ['FR','RA','AN','NC','CE']
result2 = ['FR','RE','EN','NC','CH']

result1∪ result2 = {'FR','RA','AN',NC','CE','RE','EN','CH'}

result1∩ result2 = {'FR','NC'}

 

case2. 아래의 2개의 집합이 있을 때 이 두 집합의 합집합과 교집합을 구하시오.

원소가 중복되는 다중 집합

A = { 1,1,2,2,3 }

B = { 1,2,2,4,5 }

A∪B = { 1,1,2,2,3,4,5 }

A∩B = { 1,2,2 }

교집합의 경우 A집합은 1을 2개 가지고 있고 B집합은 1을 하나 가지고 있음. 교집합은 (2,1)로 해서 1을 1개로 구성. 

합집합의 경우 max(2,1)로 해서 1을 2개로 구성.

 

만약, 문자도 원소의 갯수가 중복된다면? = 다중집합

a = 'handshake'
b = 'shake hands'

A = ['HA', 'AN', 'ND', 'DS', 'SH', 'HA', 'AK', 'KE']

B = ['SH', 'HA', 'AK', 'KE', 'HA', 'AN', 'ND', 'DS']

 

위의 경우는 우리가 지금까지 만든 자카드 함수로는 제대로 계산을 할 수가 없음. 

제대로 계산되게 하려면 합집합을 구할 때 set함수를 사용하면 안되고 collection을 사용해야함.

A = [1,1,1,2,2,3]

B = [1,1,2,2,4,5]

A∪B = { 1,1,1,2,2,3,4,5 }

A∩B = { 1,1,2,2 }

 

set함수는 합집합이 {1,1,2,2,3,4,5}로 나옴. 합집합이 자카드 유사도를 구하기 위한 합집하으로 출력되지 않음. 그래서 collection을 사용해야함.

A =[ 1, 1, 1, 2, 2, 3 ]
B =[ 1, 1, 2, 2, 4, 5 ]

import  collections 
intersect = []
result = collections.Counter(A)  & collections.Counter(B)  # 교집합
intersect = list( result.elements() ) 

result2 = collections.Counter(A) | collections.Counter(B)  # 합집합 
union = list( result2.elements() )

print(intersect )  # 교집합 출력  [1, 1, 2, 2]
print(union )    # 합집합 출력   [1, 1, 1, 2, 2, 3, 4, 5]

 

문제309. (오늘의 마지막 문제) 기존의 jacard함수를 collection을 이용한 코드로 수정해서 아래의 자카드 계수를 제대로 출력하시오.

문자를 입력하세요~ handshake

문자를 입력하세요~ shake hands

자카드 계수 :  1.0

def str_split():
    text = input('문자를 입력하세요 ~')
    result = []
    for i in range(len(text)-1):
        k = text[i:i+2]
        if k.isalpha() == True:
            result.append(k.upper())
    return result

def jacard():
    a = str_split()
    b = str_split()
    
    import  collections 
    intersect = []
    result = collections.Counter(a)  & collections.Counter(a)  # 교집합
    intersect = list( result.elements() ) 

    result2 = collections.Counter(a) | collections.Counter(b)  # 합집합 
    union = list( result2.elements() )
    
    return len(intersect)/len(union)

jacard()

 

반응형