내 마음대로 공간

고급문자열처리

고급 문자열 처리

In [3]:
## 모듈 가져오기 
import pandas as pd
import numpy as np
from pandas import Series, DataFrame

# 그래픽에 필요힌 페키지와 라이브러리를 가져 온다. 
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

%matplotlib inline

# 그래프에서 마이너스 폰트 깨지는 문제 해결 
# (폰트를 지정하면 이러한 문제가 발생하기 때문에 아래 설정)
mpl.rcParams['axes.unicode_minus'] = False

문자 인코딩 문제

- 읽기, 쓰기에서 맞는 인코딩을 사용해야 한다.
In [3]:
# 잘 읽어온다. 
pd.read_csv('data/geeks.csv')
Out[3]:
이름 직업 국적 트위터 생년월일
0 이성주 컴퓨터 프로그래머/데이터 과학자 대한민국 @LeeSeongjoo 1982-12-27
1 Rossum 컴퓨터 프로그래머 네덜란드 @gvanrossum 1956-01-31
2 Turing 컴퓨터과학자 영국 NaN 1912-06-23
In [5]:
# Encoding 문제로 오류 발생 
pd.read_csv('data/geeks_cp949.txt')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-5-0e30bd34d694> in <module>()
      1 # Encoding 문제로 오류 발생
----> 2 pd.read_csv('data/geeks_cp949.txt')

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\io\parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, skip_footer, doublequote, delim_whitespace, as_recarray, compact_ints, use_unsigned, low_memory, buffer_lines, memory_map, float_precision)
    653                     skip_blank_lines=skip_blank_lines)
    654 
--> 655         return _read(filepath_or_buffer, kwds)
    656 
    657     parser_f.__name__ = name

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\io\parsers.py in _read(filepath_or_buffer, kwds)
    403 
    404     # Create the parser.
--> 405     parser = TextFileReader(filepath_or_buffer, **kwds)
    406 
    407     if chunksize or iterator:

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\io\parsers.py in __init__(self, f, engine, **kwds)
    760             self.options['has_index_names'] = kwds['has_index_names']
    761 
--> 762         self._make_engine(self.engine)
    763 
    764     def close(self):

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\io\parsers.py in _make_engine(self, engine)
    964     def _make_engine(self, engine='c'):
    965         if engine == 'c':
--> 966             self._engine = CParserWrapper(self.f, **self.options)
    967         else:
    968             if engine == 'python':

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\io\parsers.py in __init__(self, src, **kwds)
   1580         kwds['allow_leading_cols'] = self.index_col is not False
   1581 
-> 1582         self._reader = parsers.TextReader(src, **kwds)
   1583 
   1584         # XXX

pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader.__cinit__ (pandas\_libs\parsers.c:6175)()

pandas\_libs\parsers.pyx in pandas._libs.parsers.TextReader._get_header (pandas\_libs\parsers.c:9691)()

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 0: invalid start byte
In [6]:
# Encoding 맞게 변경
pd.read_csv('data/geeks_cp949.txt', encoding='cp949')
Out[6]:
이름 기술 국적 트위터 생년월일
0 이성주 컴퓨터 프로그래머/데이터 과학자 대한민국 @LeeSeongjoo 1982-12-27
1 Rossum 컴퓨터 프로그래머 네덜란드 @gvanrossum 1956-01-31
2 Turing 컴퓨터과학자 영국 NaN 1912-06-23
In [7]:
# encoding을 지정하지 않으면 윈도우 기본 인코딩을 사용: 한글 원도우는 code page 949가 기본이다. 
frame = pd.read_csv('data/geeks.csv')
frame
Out[7]:
이름 직업 국적 트위터 생년월일
0 이성주 컴퓨터 프로그래머/데이터 과학자 대한민국 @LeeSeongjoo 1982-12-27
1 Rossum 컴퓨터 프로그래머 네덜란드 @gvanrossum 1956-01-31
2 Turing 컴퓨터과학자 영국 NaN 1912-06-23
In [8]:
# 오류발생....
frame['직업']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   2392             try:
-> 2393                 return self._engine.get_loc(key)
   2394             except KeyError:

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5239)()

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5085)()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20405)()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20359)()

KeyError: '직업'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-8-bd3fc1a3758e> in <module>()
      1 # 오류발생....
----> 2 frame['직업']

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
   2060             return self._getitem_multilevel(key)
   2061         else:
-> 2062             return self._getitem_column(key)
   2063 
   2064     def _getitem_column(self, key):

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\frame.py in _getitem_column(self, key)
   2067         # get column
   2068         if self.columns.is_unique:
-> 2069             return self._get_item_cache(key)
   2070 
   2071         # duplicate columns & possible reduce dimensionality

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\generic.py in _get_item_cache(self, item)
   1532         res = cache.get(item)
   1533         if res is None:
-> 1534             values = self._data.get(item)
   1535             res = self._box_item_values(item, values)
   1536             cache[item] = res

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\internals.py in get(self, item, fastpath)
   3588 
   3589             if not isnull(item):
-> 3590                 loc = self.items.get_loc(item)
   3591             else:
   3592                 indexer = np.arange(len(self.items))[isnull(self.items)]

C:\Users\stonw\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   2393                 return self._engine.get_loc(key)
   2394             except KeyError:
-> 2395                 return self._engine.get_loc(self._maybe_cast_indexer(key))
   2396 
   2397         indexer = self.get_indexer([key], method=method, tolerance=tolerance)

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5239)()

pandas\_libs\index.pyx in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5085)()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20405)()

pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20359)()

KeyError: '직업'
In [10]:
# 칼럼 확인
frame.columns
# 직업이 .... ㅠㅠ 칼럼명에 공백이 있다. 
Out[10]:
Index(['이름', ' 직업', ' 국적', ' 트위터', ' 생년월일'], dtype='object')
In [11]:
#' 직업' 직업 앞에 ' '공백이 들어가 있다. 
frame[' 직업']
Out[11]:
0     컴퓨터 프로그래머/데이터 과학자
1             컴퓨터 프로그래머
2                컴퓨터과학자
Name:  직업, dtype: object
In [12]:
# 칼럼명을 변경한다. 
# rename을 이용해 칼럼의 문자열을 가져와서 str.strip 시킨다. 
frame = frame.rename(columns=str.strip)
In [13]:
# 이제 '직업'으로 칼럼이 변경되었다. 
frame['직업']
Out[13]:
0     컴퓨터 프로그래머/데이터 과학자
1             컴퓨터 프로그래머
2                컴퓨터과학자
Name: 직업, dtype: object

정규식을 활용해 읽어올때 처리

In [15]:
import re
# 정규식 사용을 위해 
In [17]:
# 구분자가 공백 한개 이상인 패턴인 경우 정규식을 사용하여 공백한개 이상을 sep에 셋팅한다. 
pd.read_csv('data/ex3.csv', sep='\s+')
Out[17]:
A B C
aaa -0.264438 -1.026059 -0.619500
bbb 0.927272 0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382 1.100491

문자열 다루기

In [18]:
text = 'a, b,      성주'
In [19]:
# 문자열 분리하기(자르기)
text.split(',')
Out[19]:
['a', ' b', '      성주']
In [20]:
#앞 뒤 공백 삭제
'      안녕     하세요.     \r\n'.strip()
Out[20]:
'안녕     하세요.'
In [21]:
# split을 사용하는 경우에는 strip을 보통 같이 사용한다. 
# 내장리스트 문법( --> [t.strip() for t in text.split(',')] )으로 문자열 분리후 앞뒤 공백 제거.
items = [t.strip() for t in text.split(',')]
items
Out[21]:
['a', 'b', '성주']
In [22]:
# 문자열 합치기
':'.join(items)
Out[22]:
'a:b:성주'
In [28]:
# 문자열의 포함 여부 확인 --> in 연산자
text = 'If the columns have multiple levels, determines how the other levels are named.'
'how' in text
Out[28]:
True
In [29]:
'levels' in text
Out[29]:
True
In [30]:
# 포함된 문자열이 몇개인지 확인 
text.count('levels')
Out[30]:
2
In [33]:
# 포함된 문자열의 위치 --> 2개 이상이 존재하는 경우 첫번째 찾은 문자의 위치
text.find('the')
Out[33]:
3
In [34]:
# 없는 경우 -1 값 리턴
text.find('java')
Out[34]:
-1
In [35]:
# find와 마찬가지로 위치를 알려주지만 없는 경우 예외가 발생한다. 
text.index('python')
#text.index('java')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-f427fe37a2b1> in <module>()
      1 # find와 마찬가지로 위치를 알려주지만 없는 경우 예외가 발생한다.
----> 2 text.index('python')
      3 #text.index('java')

ValueError: substring not found
In [36]:
# 문자열 대체
text.replace(' ', '')
Out[36]:
'Ifthecolumnshavemultiplelevels,determineshowtheotherlevelsarenamed.'
In [37]:
# 빈문자와 공백문자의 차이 이해
len(' ')
Out[37]:
1
In [38]:
len('')
Out[38]:
0
In [39]:
# 대문자
text.upper()
Out[39]:
'IF THE COLUMNS HAVE MULTIPLE LEVELS, DETERMINES HOW THE OTHER LEVELS ARE NAMED.'
In [40]:
# 소문자
text.lower()
Out[40]:
'if the columns have multiple levels, determines how the other levels are named.'

정규 표현식

In [8]:
import re
# 정규식 사용을 위해 
In [45]:
text = """ 
제가 뭘 샀는데요.   어쩌구 저쩌구... 하여튼 연락 주세요. 제 번호는 
010-1234-5678 입니다. 혹시 연락이 안되면 010.4567.1234로 
부탁 드립니다. 
"""
In [44]:
# 공백(길이가 1이상의 모든)을 기준으로 분리
re.split('\s+' , text)
Out[44]:
['',
 '제가',
 '뭘',
 '샀는데요.',
 '어쩌구',
 '저쩌구...',
 '하여튼',
 '연락',
 '주세요.',
 '제',
 '번호는',
 '010-1234-5678',
 '입니다.',
 '혹시',
 '연락이',
 '안되면',
 '010.4567.1234로',
 '부탁',
 '드립니다.',
 '']
In [46]:
# 전화번호 찾기 []안의 문자는 이것들 중 하나가 나오면 이다. 리턴 결과는 리스트 형식
전화번호패턴 = '\d{3}[.-]\d{4}[-.]\d{4}'
re.findall(전화번호패턴, text)
Out[46]:
['010-1234-5678', '010.4567.1234']
In [47]:
# 정규식에서는 그룹을 만들기 위해서 ()를 사용 한다. 
그룹패턴식 = '(\d{3})[.-](\d{4})[.-](\d{4})'
In [49]:
groups = re.findall(그룹패턴식, text)
groups
## 튜플의 리스트로 반환
Out[49]:
[('010', '1234', '5678'), ('010', '4567', '1234')]
In [50]:
#() 만든 그룹은 앞에서 부터 차례로 1, 2, 3 순번이 붙는다. 순번은 1부터 시작한다. 
# r'\1-****-\3' 패턴식에서 r은 뒤의 문자열을 입력한 그대로 사용한다는 의미이다. --> c#의 @와 동일한 기능이다.
# --> 그룹1과 그룹3은 그대로 출력하고 그룹2는 ****으로 치환 한다. 
text2 = re.sub(그룹패턴식, r'\1-****-\3', text)
print(text2)
 
제가 뭘 샀는데요.   어쩌구 저쩌구... 하여튼 연락 주세요. 제 번호는 
010-****-5678 입니다. 혹시 연락이 안되면 010-****-1234로 
부탁 드립니다. 

연습

주어진 문자열에서 다음을 수행

  1. yyyy년 mm월 dd일 형식의 문자열 추출
  2. 위의 형식의 문자열을 yyyy.mm.dd형식으로 변환

문자열 : 웹 브라우저에서 위키백과 사이트로 이동해서 , 앨런 튜링을 검색한다.

In [13]:
튜링 = """앨런 매티슨 튜링(영어: Alan Mathison Turing, OBE, FRS, 1912년 6월 23일 ~ 1954년 6월 7일)은 영국의 수학자, 암호학자, 논리학자이자 컴퓨터 과학의 선구적 인물이다. 알고리즘과 계산 개념을 튜링 기계라는 추상 모델을 통해 형식화함으로써 컴퓨터 과학의 발전에 지대한 공헌을 했다.[2][3][4] 튜링 테스트의 고안으로도 유명하다. ACM에서 컴퓨터 과학에 중요한 업적을 남긴 사람들에게 매년 시상하는 튜링상은 그의 이름을 따 제정한 것이다. 이론 컴퓨터 과학과 인공지능 분야에 지대한 공헌을 했기 때문에 "컴퓨터 과학의 아버지"라고 불린다.

1945년에 그가 고안한 튜링 머신은 초보적 형태의 컴퓨터로, 복잡한 계산과 논리 문제를 처리할 수 있었다. 하지만 튜링은 1952년에 당시에는 범죄로 취급되던 동성애 혐의로 영국 경찰에 체포돼 유죄 판결을 받았다.[5] 감옥에 가는 대신 화학적 거세를 받아야 했던 그는, 2년 뒤 청산가리를 넣은 사과를 먹고 자살했다.[5]

사후 59년만인 2013년 12월 24일에 엘리자베스 2세 여왕이 크리스 그레일링 법무부 장관의 건의를 받아들여 튜링의 동성애 죄를 사면하였다. 이어서 무죄 판결을 받고 복권되었다.[5]
"""
In [14]:
# 1.yyyy년 mm월 dd일 형식의 문자열 추출
날짜패턴 = r"\d{4}년\s+\d{1,2}월\s+\d{1,2}일"
re.findall(날짜패턴, 튜링)
Out[14]:
['1912년 6월 23일', '1954년 6월 7일', '2013년 12월 24일']
In [15]:
날짜그룹패턴 = r"(\d{4})년\s+(\d{1,2})월\s+(\d{1,2})일"
re.findall(날짜그룹패턴, 튜링)
Out[15]:
[('1912', '6', '23'), ('1954', '6', '7'), ('2013', '12', '24')]
In [1]:
#날짜그룹 = r"(\d{4})년\s+(\d{2})월\s+(\d{2})일"
변환그룹패턴 = r"\1.\2.\3"
result = re.sub(날짜그룹패턴, 변환그룹패턴, 튜링)
print(result)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-1b44b974a2c7> in <module>()
      1 #날짜그룹 = r"(\d{4})년\s+(\d{2})월\s+(\d{2})일"
      2 변환그룹패턴 = r"\1.\2.\3"
----> 3 result = re.sub(날짜그룹패턴, 변환그룹패턴, 튜링)
      4 print(result)

NameError: name 're' is not defined

심화 학습

패턴에 일치하는 문자열을 찾아서 변환한뒤 다시 대체하기

변환하는 날짜 형식을 년도4자리.월2자리.일2자리 정형화된 형식으로 변환

  • 1954.6.7 --> 1954.06.07 형식으로...
In [61]:
from datetime import datetime, date, time
In [62]:
# 문자열의 형식 지정  --> 02d 표현형식(02) + 자료형(d)
# 입력 인수로 함수 넣기를 사용한다. 
# 1. 함수를 만든다. 함수는 def f(match)로 만들고 매치된 문자를 변환해서 리턴 한다.
# 2. complie을 이용해서 매치 패턴을 만든다. 
# 3. sub(함수, 문자)를 실행 한다. 

# 1 날짜 포멧을 변환하는 함수를 만든다. 매개 변수는 match
def 날짜포멧변환(m):
    value = str(m.group())
    value = re.findall(날짜그룹패턴, value)[0]    
    dt = datetime(int(value[0]), int(value[1]), int(value[2]))
    #value = '{0}-{1}-{2}'.format(value[0], value[1], value[2])
    return '{0.year}.{0.month:02d}.{0.day:02d}'.format(dt)
    #return str(value)
In [63]:
#'{0}-{1:02d}-{2:02d}'.format(datetime)
# 2 complie을 이용해 포멧함수 호출해서 변환
p = re.compile(날짜패턴)
print(p.sub(날짜포멧변환, 튜링))
앨런 매티슨 튜링(영어: Alan Mathison Turing, OBE, FRS, 1912.06.23 ~ 1954.06.07)은 영국의 수학자, 암호학자, 논리학자이자 컴퓨터 과학의 선구적 인물이다. 알고리즘과 계산 개념을 튜링 기계라는 추상 모델을 통해 형식화함으로써 컴퓨터 과학의 발전에 지대한 공헌을 했다.[2][3][4] 튜링 테스트의 고안으로도 유명하다. ACM에서 컴퓨터 과학에 중요한 업적을 남긴 사람들에게 매년 시상하는 튜링상은 그의 이름을 따 제정한 것이다. 이론 컴퓨터 과학과 인공지능 분야에 지대한 공헌을 했기 때문에 "컴퓨터 과학의 아버지"라고 불린다.

1945년에 그가 고안한 튜링 머신은 초보적 형태의 컴퓨터로, 복잡한 계산과 논리 문제를 처리할 수 있었다. 하지만 튜링은 1952년에 당시에는 범죄로 취급되던 동성애 혐의로 영국 경찰에 체포돼 유죄 판결을 받았다.[5] 감옥에 가는 대신 화학적 거세를 받아야 했던 그는, 2년 뒤 청산가리를 넣은 사과를 먹고 자살했다.[5]

사후 59년만인 2013.12.24에 엘리자베스 2세 여왕이 크리스 그레일링 법무부 장관의 건의를 받아들여 튜링의 동성애 죄를 사면하였다. 이어서 무죄 판결을 받고 복권되었다.[5]

In [60]:
p.sub?

백터화된 문자열 처리

교재 295페이지 , 297페이지의 표7-5참고

  • Series, DataFrame에서 ser함수의 용법/용도
In [17]:
# 날씨 데이터 로딩
날씨 = pd.read_excel('data/weather.xlsx')

weather 칼럼의 날씨 정보 문자열 처리

  • '/' 구분자로 날씨 정보 존재
  • 첫번째 맑음여부, 두번째 안개여부, 세번째 비여부 등의 정보 있음.
  • 여기서 첫번째 항목만 분리 표시
In [21]:
# weather 칼럼 확인
날씨[['weather']].sample(10)
Out[21]:
weather
1413 구름많음/안개
165 구름조금
613 맑음
1056 흐림/안개
1388 구름조금/안개
757 구름많음/안개
776 구름많음/안개
889 흐림/안개/비
234 맑음
431 맑음
In [23]:
# weather 열에 있는 각 문자열들을 모두 분할. 
날씨['weather'].str.split('/')[:10]
Out[23]:
0                 [구름많음]
1            [흐림, 안개, 비]
2              [흐림, 소나기]
3          [흐림, 소나기, 안개]
4    [구름많음, 안개, 천둥번개, 비]
5    [구름많음, 안개, 천둥번개, 비]
6                 [구름많음]
7             [구름많음, 안개]
8               [흐림, 안개]
9    [구름많음, 안개, 천둥번개, 비]
Name: weather, dtype: object
In [25]:
# 열의 분할된 문자리스트에서 첫번째 문자열
날씨['weather'].str.split('/').str[0][:10]
Out[25]:
0    구름많음
1      흐림
2      흐림
3      흐림
4    구름많음
5    구름많음
6    구름많음
7    구름많음
8      흐림
9    구름많음
Name: weather, dtype: object

문자열에서 전화번호 패턴만 분리하기

  • 패턴은 정규식을 사용한다.
  • 문자열의 시리즈 데이터에서 전화번호만 뽑아온다.
    • str 사용 : str은 배열의 각각의 문자를 반환한다.
      • findall : 일치하는 패턴은 모두 찾는다.
      • replace : 일치하는 패턴을 찾아서 변환 한다.
      • contains : 일치하는 패턴이 존재하는지 여부를 반환 한다.
      • slpit : 지정된 구분자로 분할 한다.
      • join : 지정된 구분자로 배열 또는 리스트를 하나의 문자열로 합친다.
In [26]:
# 시리즈에 대한 처리 
sr = Series([
    '02-1357-2468 또는 010-1234-6789입니다. ',
    '연락처: 010-2345-7890'
])
In [27]:
전화번호패턴 = r'\d{2,3}-\d{4}-\d{4}'
sr.str.findall(전화번호패턴)
Out[27]:
0    [02-1357-2468, 010-1234-6789]
1                  [010-2345-7890]
dtype: object
In [78]:
전화번호그룹패턴 = r'(\d{2,3})-(\d{4})-(\d{4})'
전화번호변환패턴 = r'\1-****-\3'
#sr.str.replace(전화번호그룹패턴, 전화번호변환패턴)
In [79]:
sr.str.replace(전화번호그룹패턴, 전화번호변환패턴)
Out[79]:
0    02-****-2468 또는 010-****-6789입니다. 
1                    연락처: 010-****-7890
dtype: object
In [80]:
# .str[0] 쓰는 이유. --> str.get[0] 과 동일한 의미이다. 
# 첫번째 항목(문자열)을 가져온다. 0 인덱스의 두번째 항목인 010-1234-5678은 반환되지 않는다. 
전번 = sr.str.findall(전화번호패턴).str[0]
전번
Out[80]:
0     02-1357-2468
1    010-2345-7890
dtype: object
In [81]:
전번.str.replace(전화번호그룹패턴, 전화번호변환패턴)
Out[81]:
0     02-****-2468
1    010-****-7890
dtype: object
In [82]:
## contains 함수를 이용해서 날씨에 비온 것만 확인 
날씨['weather'].str.contains('비')[:5]
Out[82]:
0    False
1     True
2    False
3    False
4     True
Name: weather, dtype: bool
In [83]:
## contains 함수를 이용해 날씨에 비 또는 눈이 내린 것을 정규식을 이용해서 확인 
날씨['weather'].str.contains('비|눈')[:5]
Out[83]:
0    False
1     True
2    False
3    False
4     True
Name: weather, dtype: bool
In [84]:
# 분할하고 다시 조인해서 구분자 변경
날씨['weather'].str.split('/').str.join(':')[:10]
Out[84]:
0              구름많음
1           흐림:안개:비
2            흐림:소나기
3         흐림:소나기:안개
4    구름많음:안개:천둥번개:비
5    구름많음:안개:천둥번개:비
6              구름많음
7           구름많음:안개
8             흐림:안개
9    구름많음:안개:천둥번개:비
Name: weather, dtype: object
In [89]:
# replace함수를 이용해 '/'를  ':' 로 변환 
날씨['weather'].str.replace('/', ':')[:10]
Out[89]:
0              구름많음
1           흐림:안개:비
2            흐림:소나기
3         흐림:소나기:안개
4    구름많음:안개:천둥번개:비
5    구름많음:안개:천둥번개:비
6              구름많음
7           구름많음:안개
8             흐림:안개
9    구름많음:안개:천둥번개:비
Name: weather, dtype: object

Series에서 str함수를 사용할때와 사용하지 않을땡의 차이

Series에서 str 함수를 사용하여 replace

In [88]:
# str 함수를 사용할때 --> 내부 셀들의 문자열에 대해서 repace 수행
날씨['weather'].str.replace('구름많음', 'cloudy')[:10]
Out[88]:
0              cloudy
1             흐림/안개/비
2              흐림/소나기
3           흐림/소나기/안개
4    cloudy/안개/천둥번개/비
5    cloudy/안개/천둥번개/비
6              cloudy
7           cloudy/안개
8               흐림/안개
9    cloudy/안개/천둥번개/비
Name: weather, dtype: object

Series에서 str함수를 사용하지 않고 replace

In [90]:
# str 함수를 쓰지 않을때의 결과 차이 확인 --> 4,5,7,9 색인의 변환 결과가 다르다. 
#즉 내부 셀의 텍스트를 가지고 처리를 하는가 셀 전체를 대상으로 처리하는가의 차이를 보인다. 
# 셀 자체에 대해서 replace 수행... --> 셀값 전체가 구름많음 일때만 교체된다. 
날씨['weather'].replace('구름많음', 'cloudy')[:10]
Out[90]:
0            cloudy
1           흐림/안개/비
2            흐림/소나기
3         흐림/소나기/안개
4    구름많음/안개/천둥번개/비
5    구름많음/안개/천둥번개/비
6            cloudy
7           구름많음/안개
8             흐림/안개
9    구름많음/안개/천둥번개/비
Name: weather, dtype: object

지역별 눈 또는 비가 온 날씨와 안온 날씨를 표시하기

In [91]:
# 지역 도수 확인 
날씨['location'].value_counts()
Out[91]:
suwon    730
seoul    730
Name: location, dtype: int64
In [92]:
# 눈비 확인 
눈비 = 날씨['weather'].str.contains('눈|비')
In [93]:
눈비 = 눈비.replace({True: '눈비', False: '안옴'})
In [94]:
# 위 불리언 필터를 이용해서 눈과 비가 온 날과 안온날로 분리된 그룹으로 각 지역의 온도의 평균을 구할 수 있다. 
날씨.pivot_table('avgTemp', aggfunc='mean', index='location', columns=눈비)
Out[94]:
weather 눈비 안옴
location
seoul 14.273399 13.015939
suwon 13.628934 12.996435
In [96]:
# 날씨의 weather에서 글자가 많은 것을 선택....
필터 = 날씨['weather'].str.len() > 10
날씨[필터]['weather'].sample(10)
Out[96]:
560     구름많음/소나기/안개/천둥번개
1244         구름많음/안개/이슬비
1237         흐림/비/안개/이슬비
479     구름많음/소나기/안개/천둥번개
1174         흐림/비/안개/이슬비
831        구름많음/소나기/천둥번개
1410       구름많음/비/안개/이슬비
442          구름조금/소나기/안개
1457        흐림/비/안개/천둥번개
1019        흐림/비/안개/진눈개비
Name: weather, dtype: object
In [99]:
# 날씨의 weather에서 날씨 속성이 여러개인것. (2개 이상인 것들만 추출)
# .str.split('/') 의 결과는 문자열이 아니지만 문자열과 비슷하게 취급... 헷갈림....
# split()한 것들을 str을 이용해 길이를 측정.
복수날씨필터 = 날씨['weather'].str.split('/').str.len() > 2
날씨[복수날씨필터]['weather']
Out[99]:
1                흐림/안개/비
3              흐림/소나기/안개
4         구름많음/안개/천둥번개/비
5         구름많음/안개/천둥번개/비
9         구름많음/안개/천둥번개/비
17               흐림/안개/비
18             구름조금/안개/비
22               흐림/안개/비
28          흐림/안개/천둥번개/비
40               흐림/안개/비
41             흐림/안개/이슬비
42               흐림/안개/비
43             흐림/천둥번개/비
59               흐림/안개/비
89             구름많음/안개/비
93             구름많음/안개/비
97               흐림/안개/비
106            구름많음/안개/비
107            구름많음/안개/비
115            구름많음/안개/비
133       구름많음/안개/천둥번개/눈
135            구름조금/안개/눈
139            구름많음/안개/눈
147            구름많음/안개/눈
150            구름조금/안개/눈
154              흐림/안개/비
156              흐림/안개/비
157     구름많음/소나기/안개/천둥번개
158     구름많음/소나기/안개/천둥번개
162       구름많음/안개/천둥번개/비
              ...       
1344           구름많음/비/안개
1352           구름조금/비/안개
1353      구름조금/비/안개/천둥번개
1366             흐림/비/안개
1369           구름많음/비/안개
1370         흐림/비/안개/이슬비
1375             흐림/비/안개
1386         흐림/비/안개/이슬비
1397           구름많음/비/안개
1409           구름많음/비/안개
1410       구름많음/비/안개/이슬비
1411       구름많음/비/소나기/안개
1412      구름많음/비/안개/천둥번개
1415         구름많음/소나기/안개
1416         구름많음/소나기/안개
1418             흐림/비/안개
1423             흐림/비/안개
1428             흐림/비/안개
1439           구름많음/비/안개
1441             흐림/비/안개
1446             흐림/비/안개
1449             흐림/비/안개
1450           흐림/소나기/안개
1451             흐림/비/안개
1452             흐림/비/안개
1453             흐림/비/안개
1454           구름많음/비/안개
1455             흐림/비/안개
1456         구름많음/안개/이슬비
1457        흐림/비/안개/천둥번개
Name: weather, Length: 255, dtype: object
In [ ]:
 
728x90

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading