자꾸 잊어버려서 매번 같은걸 구글링하는데에 지쳐 결국에는 정리해두는 몇가지 팁. 라이브러리별로 계속해서 업데이트할 예정이다. (최종 업데이트 2020.06.19)
json
JSON이란?
- Javascript Object Notation 의 약자
- 웹서버와 클라이언트간 데이터 교환에 유리하다.
- 파이썬의
dict
형과 구조가 닮아있다.
JSON 파일 만들기
json
패키지를 import 하고, json 형태로 만들 dict 형태의 데이터를 하나 만들어준다.
import json
customer = {
'id' : '000001'
'name' : '홍길동'
'history': [
{'date' : '2018-05-22', 'log' : True},
{'date' : '2018-05-23', 'log' : False}
]
}
여기서 json.dumps
를 사용하면 json 데이터가 만들어진다.
ensure_ascii
옵션을False
로 지정하면 데이터가 utf-8 로 저장된다.
json_test = json.dumps(customer, indent = 4, ensure_ascii = False)
파일로 쓰기
파일로 쓸때는 json.dump
를 사용하면 된다. (아까 썼던 dumps
와 헷갈리지 않게 주의!)
with open('json_tutorial.json', 'w', encoding='utf-8') as f:
json.dump(customer, f, ensure_ascii = False, indent = 4)
json 파일 읽기
읽을 때는 json.load
를 사용한다. (Deserialize fp (a .read()-supporting file-like object containing a JSON document) to a Python object)
with open('json_tutorial.json') as f:
json_test = json.load(f)
유사한 함수로는 json.loads
가 있는데, 여기서 끝에 붙은 ‘s’는 ‘string’을 뜻한다. .load
는 파일을 json 형식으로 만들어준다면, .loads
는 문자열을 인자로 받아 json 파일을 반환한다.
네이버 API에서 urllib
를 이용해 각종 검색 결과 데이터를 가져왔을 때에는 받아온 데이터의 타입이 문자열이었기 때문에 json.loads
를 사용해 json 타입으로 변환시킬 수 있었다.
정리
json. | 기능 | input | output |
---|---|---|---|
dump | Serialize | 파이썬 객체 | json 파일 |
dumps | 파이썬 객체 | json 형식의 문자열 | |
load | Deserialize | json 파일 | 파이썬 객체 |
loads | json 구조를 포함한 문자열 | 파이썬 객체 |
- 이때,
loads
로 받은 문자열이 유효한 json 구조를 포함하고 있지 않으면,JSONDecodeError
가 발생한다. - 위 표에서 파이썬 객체란 리스트와 딕셔너리를 뜻한다. 원한다면 임의의 클래스 인스턴스를 json으로 직렬화(serialize)할수도 있지만 좀 더 복잡한 과정이 요구된다.
- 참고 :
pickle
- 피클 모듈
json에 반해, pickle은 임의의 복잡한 파이썬 객체들을 직렬화할 수 있다. 하지만 파이썬에 국한되고 다른 언어로 작성된 응용 프로그램들과 통신하는데 사용될 수 없다.
konlpy
jpype 설치 후 형태소 분석기 실행시 에러
- jpype 에러가 java error 로 뜨는 경우가 많이 있다. (Jpype 랑 Java 버전들간의 궁합이 있는 것 같음..) 그에 따라서
pip install jpype
가 먹힐 때도 있고conda install -c conda-forge jpype1
이 먹힐때도 있다. 한번 다 uninstall 해보고 두가지 방법 다 시도해보기.에러메시지 :
... init_jvm() takes 0, 1 positional arguments but 2 were given ...
matplotlib
plt.subplot
로 여러개의 그래프 동시에 그리기
import matplotlib.pyplot as plt
plt.figure(figsize = (10, 6)) # 단위 : 인치
plt.subplot(221)
plt.subplot(222)
plt.subplot(212)
plt.show()
- 인자로 받는 숫자의 의미
plt.subplot(nrows, ncols, plot_number)
- 각각에 해당하는 숫자가 다 10보다 작으면, 세자리 수로 표현해 그대로 넣어줄 수 있다.
- 221: 행 방향으로 2개, 열 방향으로 2개의 그래프를 그릴 것인데, 그 중에서 첫번째 자리에 그려라.
- 222: 행 방향으로 2개, 열 방향으로 2개의 그래프를 그릴 것인데, 그 중에서 두번째 자리에 그려라.
pandas
- 데이터프레임의 한 열에 어떤 값들이 어느정도의 빈도로 있는지 알고 싶다면?
- Series 형 데이터에
.value_counts()
메소드를 사용하면 어떤 값들이 어떤 빈도로 나타나는지 확인할 수 있다. - 어떤 값들이 있는지 보여주는
.unique()
의 기능에 각 값의 빈도까지 추가적으로 보여준다고 생각하면 된다.
- Series 형 데이터에
>>> import seaborn as sns
>>> iris = sns.load_dataset('iris') # seaborn 라이브러리에 내장된 iris 데이터셋 불러오기
>>> iris.head()
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
>>> iris['species'].unique()
array(['setosa', 'versicolor', 'virginica'], dtype=object)
>>> iris['species'].value_counts()
versicolor 50
setosa 50
virginica 50
Name: species, dtype: int64
- 작업한 데이터프레임을 외부 파일로 저장할 때
pd.DataFrame.to_csv()
header=False
: 열 이름을 저장하고 싶지 않은 경우index=False
: 행 index 를 저장하고 싶지 않은 경우
numpy
np.argsort
배열을 인자로 받아서 원소들의 순서에 따라 그 index 를 배열로 반환한다.>>> import numpy as np >>> arr = np.array([44, 33, 11, 22]) >>> np.argsort(arr) array([2, 3, 1, 0])
np.bincount
정수를 원소로 가지는 배열에 대해 각 숫자의 빈도를 0 부터 차례대로 계산해 그 결과를 배열로 반환한다.>>> x = np.array([0, 1, 2, 3, 4]) >>> np.bincount(x) array([1, 1, 1, 1, 1]) >>> y = np.array([1, 3, 5, 7, 1, 3, 5, 7]) >>> np.bincount(y) array([0, 2, 0, 2, 0, 2, 0, 2])
np.sort
- 내림차순으로 정렬하기 :
np.sort(x)[::-1]
- x 를 오름차순으로 정렬한 후, mirror view 를 만들게 된다.
- 내림차순으로 정렬하기 :
transpose
vsreshape
reshape
은 보통 총 차원의 수를 줄이거나 늘릴 때 사용한다.transpose
는 총 차원의 수는 변동 없이, 차원끼리 자리를 바꾸고 싶을 때 사용한다.- 예를 들어, (num_data, height, width, num_channels) 의 데이터를 (num_data, num_channels, height, width) 의 형태로 바꾸고 싶다면
transpose
가 적합하다.
- 예를 들어, (num_data, height, width, num_channels) 의 데이터를 (num_data, num_channels, height, width) 의 형태로 바꾸고 싶다면
>>> x = np.arange(24).reshape(2,3,4)
>>> x
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> x.transpose(2,1,0)
array([[[ 0, 12],
[ 4, 16],
[ 8, 20]],
[[ 1, 13],
[ 5, 17],
[ 9, 21]],
[[ 2, 14],
[ 6, 18],
[10, 22]],
[[ 3, 15],
[ 7, 19],
[11, 23]]])
>>> x.reshape(4,3,2) # transpose 와 결과가 다르니 주의!
array([[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]],
[[18, 19],
[20, 21],
[22, 23]]])
re
특정 패턴을 만족하는 문자열 찾기
re.search(조건, 대상문자열)
를 사용해 특정 패턴을 만족하는 문자열을 찾을 수 있다.
>>> import re
>>> target = "Jimin Sun 02-1234-5678 sun@ji.min 대한민국 78910"
>>> re.search('\d+', target) # 숫자가 한개 이상 연속되는 부분을 찾아라.
<_sre.SRE_Match object; span=(10, 12), match='02'>
- 조건을 만족하는 첫번째 문자열에 해당하는 부분이 위와 같은 형식로 반환된다.
- 조건을 만족하는 부분이 없으면 아무것도 반환되지 않는다.
여기서 일치되는 부분을 문자열로 얻고 싶다면, 결과에 .group()
을 실행시키면 된다.
>>> re.search('\d+', target).group()
'02'
매칭되는 문자열을 전부 얻고 싶으면 re.findall()
함수를 쓴다.
>>> re.findall('\d+', target)
['02', '1234', '5678', '78910'] # 이렇게 매칭되는 것들을 리스트로 받을 수 있다.
re 조건에 쓰이는 ( ) 와 [ ] 의 차이
()
는 내가 하나의 그룹으로 묶어서 찾고 싶은 문자열을 표현할때 쓴다.'(abc)'
는 abc 문자열을 통째로 찾는다.
[]
는 여러가지 조건을 동시에 표현하고 싶을 때 쓸 수 있다.'[abc]'
는 a 또는 b 또는 c를 의미한다.
>>> text = 'abcd'
>>> re.findall('(abc)', text)
['abc']
>>> re.findall('[abc]', text)
['a', 'b', 'c']
>>> re.findall('(abd)', text)
[]
>>> re.findall('[abd]', text)
['a', 'b', 'd']
urllib
Url에 한글이 섞여있으면 Request
요청시 오류가 발생한다.
이때, urllib.parse.quote()
를 사용하면 한글을 퍼센트 인코딩이 적용된 값으로 바꿔줄 수 있다.
>>> import urllib
>>> import urllib.request import urlopen, Request
>>>
>>> urllib.parse.quote('한글문자열')
'%ED%95%9C%EA%B8%80%EB%AC%B8%EC%9E%90%EC%97%B4'
만약 퍼센트 인코딩을 다시 한글로 바꿔주고 싶다면, urllib.parse.unquote()
를 사용하면 쉽게 해결할 수 있다.
>>> urllib.parse.unquote('%ED%95%9C%EA%B8%80%EB%AC%B8%EC%9E%90%EC%97%B4')
'한글문자열'
wordcloud
- 분명 wordcloud 패키지를 설치했는데, import 할때
ImportError: DLL load failed: The specified module could not be found.
또는ImportError: DLL load failed: 지정된 모듈을 찾을 수 없습니다.
오류가 발생한다면?
wordcloud 패키지를 설치하면 wordcloud 패키지를 작동하는데에 요구되는 pillow 패키지도 자동으로 설치된다. 그런데
conda
로 wordcloud 패키지를 설치한 경우에는 때때로 pillow만 최신 버전으로 설치가 되지 않아 패키지를 불러오지 못하는 오류가 발생한다. 5.1.1 버전 대신 5.1.0 버전이 깔리는 것이다. 그리고 이후에pip
로 최신 버전을 설치하려고 해도, 이미 패키지가 설치가 되어있기 때문에 설치를 건너뛰게 된다.
따라서pip
를 이용하여 최신 버전의 pillow 패키지를 먼저 받고, 이후에 wordcloud 패키지를 받아주어야 한다. 이전에 wordcloud 를 설치한 적이 있다면 1.부터, 설치한 적이 없다면 5.부터 아래의 과정을 참고하면 된다.
- 터미널 또는 anaconda prompt 에서 wordcloud의 설치 여부, 버전과 어떤 관리 프로그램(pip, conda, conda-forge)을 통해 설치되었는지에 대한 정보를 확인한다.
╰─$ conda list wordcloud # packages in environment at /usr/local/anaconda3: # wordcloud 1.4.1 py36_0 <pip>
pip uninstall wordcloud
과conda remove wordcloud
을 통해 먼저 패키지를 깨끗하게 지운다.╰─$ pip uninstall wordcloud ... ╰─$ conda remove wordcloud ...
pillow
패키지도 깨끗하게 지워준다. 먼저 어떻게 설치되어있는지 확인한다.╰─$ conda list pillow # packages in environment at /usr/local/anaconda3: # pillow 4.2.1 py36h0263179_0
- 같은 방식으로 지워준다.
╰─$ conda remove pillow
- 이제 두 패키지들을 다시 설치해야한다. 먼저 pillow를 반드시
pip
를 이용해 깔아준다. 그러면 자동으로 가장 최신 버전의 pillow 패키지가 설치될 것이다. (2018.6.25 기준 5.1.0 버전)╰─$ pip install pillow Collecting pillow Downloading https://files.pythonhosted.org/packages/9c/7b/f22381dec311c2771541e6d37dd47c8a3000c4b8f61c578bf48585422c11/Pillow-5.1.0-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl (3.6MB) 100% |████████████████████████████████| 3.6MB 664kB/s Installing collected packages: pillow Successfully installed pillow-5.1.0
- 다음으로 wordcloud를 설치하는데, 이번에는
conda-forge
를 이용한다.╰─$ conda install -c conda-forge wordcloud
- 1.4.1 버전의 wordcloud 패키지와 5.1.0 버전의 pillow 패키지가 잘 깔려있는지 확인한다.
╰─$ conda list wordcloud # packages in environment at /usr/local/anaconda3: # wordcloud 1.4.1 py36_0 conda-forge
╰─$ conda list pillow # packages in environment at /usr/local/anaconda3: # Pillow 5.1.0 <pip> pillow 5.0.0 py36_0 conda-forge
- import 가 문제없이 되는지 확인한다.
╰─$ python Python 3.6.5 |Anaconda custom (64-bit)| (default, Apr 26 2018, 08:42:37) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import wordcloud >>> exit()
나는 오히려 내 컴퓨터에서 잘 돌아가던 옛날 4.2.1 버전 pillow를 포스팅을 작성하면서 업데이트 했더니
Incompatible library version: _imaging.cpython-36m-darwin.so requires version 9.0.0 or later, but libtiff.5.dylib provides version 8.0.0
를 포함한 엄청나게 긴 오류가 떴다. 그리고 구글링 끝에 찾은 아래의 코드를 통해 가능한 모든 패키지들을 업데이트 해줬더니 해결되었다. 너무 오랫동안 많은 패키지들을 업데이트 하지 않고 방치하고 있다가, pillow만 최신 버전으로 업데이트를 해서 버전간 dependency 문제가 발생한듯하다.╰─$ conda update --all