오억년만에 나타나서 처음 쓰는 글은 pd.read_csv할 때 utf-8, utf-16, 심지어는 cp949까지도 오류날 때 해결하는 방법이다.

 

 

[python] 파이썬 공공데이터 csv 파일 읽어오기_인코딩 에러 해결

회사에서 진행하는 데이터분석 아카데미 프로젝트 마감이 얼마 남지 않았다. 데이터 수집은 다했는데 전처리가 관건일듯.. 공공데이터 포털사이트에서 다운받은 cvs 파일을 pandas 모듈을 이용해

javagirl.tistory.com

 

위의 블로그가 엄청 큰 도움이 됐는데, 걍 결론적으로 엑셀 파일을 csv로 저장할 때 애초에 인코딩을 utf-8로 하는것이었다.

 

엑셀에서 엄청 긴 숫자를 입력하면 얘가 자동적으로 숫자로 인식해서 막 16e+06 이런식으로 지멋대로 숫자로 변환하는데 그게 싫어서 full 숫자로 저장하게 하려고 csv로 저장해서 python에서 불러오는 걸 하려고 했었다.

 

내가 현재 일하고 있는 회사에서는 이런식으로 숫자가 엄청 길게 기재되는 경우가 매우 빈번해서 이런 아주 간단한 부분을 확실히 알고 넘어가야 했다.

 

엑셀을 csv로 저장할 때 인코딩 오류로 열리지 않을 때는 애초에 엑셀에서 엑셀 메뉴 > 파일 > 다른이름으로 저장 > 파일형식 : csv utf8(쉼표로분리)로 저장 하면 된다.

 

 

킹갓 tqdm을 아는가? 나만 몰랐던 이야기라면 그건 좀 아쉽군...

 

tqdm

 

파이썬 반복문 어디까지 진행되었는지 표시하기: tqdm 라이브러리

반복문을 돌리면 작업이 어디까지 진행된 건지, 되고는 있는 건지 궁금할 때가 많이 있습니다. 주피터 노트북 화면을 바라보며 반복문을 돌린 셀의 별표가 사라지길 계속 기다리기도 조금 답답

hogni.tistory.com

 

for문에 tqdm을 사용하면 이 친구가 언제 다 돌아가는지 확인할 수 있어서 매우 유용하다. 

 

import fitz, os
import pandas as pd
from tqdm import tqdm

path_dir = './'
file_list = os.listdir(path_dir)
# print(file_list) # 현재폴더(./) 안에 있는 파일명들이 리스트화되어 들어가 있다.

for data in tqdm(file_list) :
    if '.pdf' in data :
        doc = fitz.open('./{}'.format(data))
        page = doc.loadPage(0)
        pix = page.getPixmap()
        output = "../pdf2png/{}.png".format(data.replace('.pdf',''))
        pix.writePNG(output)

그럼 이런식으로 볼 수 있음

 

따봉 tqdm아 고마워!

 

 

 

pdf2image라는 모듈이 있으나 poppler에서 계속 오류가 났던 나는 차선책을 찾게 되었는데, 속도 면에서는 얼마나 차이가 나는지는 모르겠지만 일단 내가 PyMuPDF를 사용해 본 결론으로는 굉장히 느리다ㅋㅋ... 코드도 느릴만하긴하지만.. 그래도 PyMuPDF는 원하는 PDF 페이지만을 선택해서 이미지화 할 수도 있기 때문에 나름 유용하다.

 

사실 pdf 파일을 이미지로 바꾸기만 하면 되는거 아니겠어? pdf2image모듈을 못 사용하니 꿩 대신 닭을 사용했다.

 

PyMuPDF

 

pymupdf/PyMuPDF

Python bindings for MuPDF's rendering library. Contribute to pymupdf/PyMuPDF development by creating an account on GitHub.

github.com

pip install -U pymupdf 를 한 후,

 

요 이미지대로 수행하면 png 파일로 나온다.

 

이 방식으로 png 파일로 만들 수 있는데, 이 png 파일을 jpg 파일로 바꾸고 싶다면... Pillow를 사용해도 될거같고 사실 걍 저 확장자만 바꿔줘도 될거같기도 하고.. (그렇다 png를 jpg로 바꿔주면 또 그렇게 잘 됨 굿 ^^)

암튼! 다들 pdf2image에 고생하지 말고 나처럼 꿩대신 닭으로도 도움 얻길!

 

 

 

 

 

 

[Pandas] 문자열(str) 처리법

Pandas에는 문자열을 다루는 여러 함수가 존재합니다.e메일 주소를 이용하여 어떤 종류들의 함수가 있는지...

blog.naver.com

 

판다스에서 문자열 처리하려면 .str을 써야한다.

 

 

 

판다스 정리4

분할

In [25]:
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important;}</style>"))
In [10]:
import pandas as pd

emp = pd.read_csv("c:/data/emp3.csv")
emp
Out[10]:
index empno ename job mgr hiredate sal comm deptno
0 1 7839 KING PRESIDENT NaN 1981-11-17 0:00 5000 NaN 10
1 2 7698 BLAKE MANAGER 7839.0 1981-05-01 0:00 2850 NaN 30
2 3 7782 CLARK MANAGER 7839.0 1981-05-09 0:00 2450 NaN 10
3 4 7566 JONES MANAGER 7839.0 1981-04-01 0:00 2975 NaN 20
4 5 7654 MARTIN SALESMAN 7698.0 1981-09-10 0:00 1250 1400.0 30
5 6 7499 ALLEN SALESMAN 7698.0 1981-02-11 0:00 1600 300.0 30
6 7 7844 TURNER SALESMAN 7698.0 1981-08-21 0:00 1500 0.0 30
7 8 7900 JAMES CLERK 7698.0 1981-12-11 0:00 950 NaN 30
8 9 7521 WARD SALESMAN 7698.0 1981-02-23 0:00 1250 500.0 30
9 10 7902 FORD ANALYST 7566.0 1981-12-11 0:00 3000 NaN 20
10 11 7369 SMITH CLERK 7902.0 1980-12-09 0:00 800 NaN 20
11 12 7788 SCOTT ANALYST 7566.0 1982-12-22 0:00 3000 NaN 20
12 13 7876 ADAMS CLERK 7788.0 1983-01-15 0:00 1100 NaN 20
13 14 7934 MILLER CLERK 7782.0 1982-01-11 0:00 1300 NaN 10
In [11]:
count, bin_dividers = np.histogram(emp.sal,bins=3)
print(count)
print(bin_dividers) # 경계값 리스트
[8 5 1]
[ 800. 2200. 3600. 5000.]
In [12]:
bin_names = ['저소득','중간소득','고소득']
emp['sal_divide'] = pd.cut(x=emp.sal,bins=bin_dividers,labels=bin_names)
emp
Out[12]:
index empno ename job mgr hiredate sal comm deptno sal_divide
0 1 7839 KING PRESIDENT NaN 1981-11-17 0:00 5000 NaN 10 고소득
1 2 7698 BLAKE MANAGER 7839.0 1981-05-01 0:00 2850 NaN 30 중간소득
2 3 7782 CLARK MANAGER 7839.0 1981-05-09 0:00 2450 NaN 10 중간소득
3 4 7566 JONES MANAGER 7839.0 1981-04-01 0:00 2975 NaN 20 중간소득
4 5 7654 MARTIN SALESMAN 7698.0 1981-09-10 0:00 1250 1400.0 30 저소득
5 6 7499 ALLEN SALESMAN 7698.0 1981-02-11 0:00 1600 300.0 30 저소득
6 7 7844 TURNER SALESMAN 7698.0 1981-08-21 0:00 1500 0.0 30 저소득
7 8 7900 JAMES CLERK 7698.0 1981-12-11 0:00 950 NaN 30 저소득
8 9 7521 WARD SALESMAN 7698.0 1981-02-23 0:00 1250 500.0 30 저소득
9 10 7902 FORD ANALYST 7566.0 1981-12-11 0:00 3000 NaN 20 중간소득
10 11 7369 SMITH CLERK 7902.0 1980-12-09 0:00 800 NaN 20 NaN
11 12 7788 SCOTT ANALYST 7566.0 1982-12-22 0:00 3000 NaN 20 중간소득
12 13 7876 ADAMS CLERK 7788.0 1983-01-15 0:00 1100 NaN 20 저소득
13 14 7934 MILLER CLERK 7782.0 1982-01-11 0:00 1300 NaN 10 저소득

더미변수

In [13]:
pd.get_dummies(emp.deptno)
Out[13]:
10 20 30
0 1 0 0
1 0 0 1
2 1 0 0
3 0 1 0
4 0 0 1
5 0 0 1
6 0 0 1
7 0 0 1
8 0 0 1
9 0 1 0
10 0 1 0
11 0 1 0
12 0 1 0
13 1 0 0

문자형을 날짜형으로 변환

In [14]:
df = pd.read_csv("c:/data/studyfile/stock-data.csv")
print(df.info())
df.head()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   Date    20 non-null     object
 1   Close   20 non-null     int64 
 2   Start   20 non-null     int64 
 3   High    20 non-null     int64 
 4   Low     20 non-null     int64 
 5   Volume  20 non-null     int64 
dtypes: int64(5), object(1)
memory usage: 1.1+ KB
None
Out[14]:
Date Close Start High Low Volume
0 2018-07-02 10100 10850 10900 10000 137977
1 2018-06-29 10700 10550 10900 9990 170253
2 2018-06-28 10400 10900 10950 10150 155769
3 2018-06-27 10900 10800 11050 10500 133548
4 2018-06-26 10800 10900 11000 10700 63039
In [15]:
df[['Date']] = pd.to_datetime(df.Date)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 6 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   Date    20 non-null     datetime64[ns]
 1   Close   20 non-null     int64         
 2   Start   20 non-null     int64         
 3   High    20 non-null     int64         
 4   Low     20 non-null     int64         
 5   Volume  20 non-null     int64         
dtypes: datetime64[ns](1), int64(5)
memory usage: 1.1 KB
In [16]:
df.Date.dt.year.tail()
Out[16]:
15    2018
16    2018
17    2018
18    2018
19    2018
Name: Date, dtype: int64
In [17]:
df.Date.dt.month.head()
Out[17]:
0    7
1    6
2    6
3    6
4    6
Name: Date, dtype: int64
In [18]:
df.Date.dt.day.head()
Out[18]:
0     2
1    29
2    28
3    27
4    26
Name: Date, dtype: int64

인덱스를 날짜형으로 만들기

In [19]:
df.set_index('Date',inplace=True)
df
Out[19]:
Close Start High Low Volume
Date
2018-07-02 10100 10850 10900 10000 137977
2018-06-29 10700 10550 10900 9990 170253
2018-06-28 10400 10900 10950 10150 155769
2018-06-27 10900 10800 11050 10500 133548
2018-06-26 10800 10900 11000 10700 63039
2018-06-25 11150 11400 11450 11000 55519
2018-06-22 11300 11250 11450 10750 134805
2018-06-21 11200 11350 11750 11200 133002
2018-06-20 11550 11200 11600 10900 308596
2018-06-19 11300 11850 11950 11300 180656
2018-06-18 12000 13400 13400 12000 309787
2018-06-15 13400 13600 13600 12900 201376
2018-06-14 13450 13200 13700 13150 347451
2018-06-12 13200 12200 13300 12050 558148
2018-06-11 11950 12000 12250 11950 62293
2018-06-08 11950 11950 12200 11800 59258
2018-06-07 11950 12200 12300 11900 49088
2018-06-05 12150 11800 12250 11800 42485
2018-06-04 11900 11900 12200 11700 25171
2018-06-01 11900 11800 12100 11750 32062
In [20]:
df.index
Out[20]:
DatetimeIndex(['2018-07-02', '2018-06-29', '2018-06-28', '2018-06-27',
               '2018-06-26', '2018-06-25', '2018-06-22', '2018-06-21',
               '2018-06-20', '2018-06-19', '2018-06-18', '2018-06-15',
               '2018-06-14', '2018-06-12', '2018-06-11', '2018-06-08',
               '2018-06-07', '2018-06-05', '2018-06-04', '2018-06-01'],
              dtype='datetime64[ns]', name='Date', freq=None)
In [21]:
df.index.year
Out[21]:
Int64Index([2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018,
            2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018],
           dtype='int64', name='Date')
In [22]:
df.index.month
Out[22]:
Int64Index([7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6], dtype='int64', name='Date')
In [23]:
df.index.day
Out[23]:
Int64Index([2, 29, 28, 27, 26, 25, 22, 21, 20, 19, 18, 15, 14, 12, 11, 8, 7, 5,
            4, 1],
           dtype='int64', name='Date')

+ Recent posts