일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- numpy
- SQL
- math
- Python
- django
- Apache
- Mac
- PySpark
- GIT
- Github
- gas
- c#
- 파이썬
- PANDAS
- Excel
- PostgreSQL
- Google Excel
- dataframe
- array
- list
- Tkinter
- Redshift
- hive
- Google Spreadsheet
- Java
- google apps script
- Kotlin
- matplotlib
- string
- Today
- Total
달나라 노트
Python Pandas : pandas와 BytesIO를 이용하여 Bytes type csv data 읽어오기/Bytes type csv 데이터를 DataFrame으로 바꾸기 본문
Python Pandas : pandas와 BytesIO를 이용하여 Bytes type csv data 읽어오기/Bytes type csv 데이터를 DataFrame으로 바꾸기
CosmosProject 2022. 12. 29. 20:13
requests library와 API를 이용하다보면 csv format의 데이터를 얻어올 때가 있습니다.
그 결과값은 API를 어떻게 만드냐에 따라 달라질 수 있지만 주로 보이는 형태는 아래와 같습니다.
import requests
api_endpoint = 'https://test_api/get_data'
response = requests.get(api_endpoint)
print(response.status_code)
print(response.content)
print(type(response.content))
-- Result
200
b'modelno,name,price,weight\r\nAGH1341,Laptop,1300000,1200\r\nSOE1029,Desktop,1800000,3500\r\nMSO6503,Keyboard,150000,800\r\nOSW3961,Monitor,380000,1800\r\n'
<class 'bytes'>
일단 위 코드를 봅시다.
위 코드는 requests library를 이용해서 https://test_api/get_data 라는 URL을 가진 API에 요청을 보내는 코드입니다.
그리고 그 결과를 받아서 결과가 뭔지 출력해보는 것이죠.
출력되는 결과를 보면 각각 다음과 같습니다.
1. response.status_code
이것은 URL로 요청을 보낸 후 서버로부터 제가 보낸 요청이 어떻게 처리되었는지를 나타내는 코드입니다.
위 코드의 결과로서 200이 출력되었습니다.
이 중에서 200은 정상적으로 요청이 처리되었고, 그 결과값도 서버로부터 정상적으로 전달되었음을 의미합니다.
2. response.content
content는 URL로 요청을 한 후 해당 URL에 반응하는 API가 작동하여 서버로부터 받은 내용을 담고 있는 속성입니다.
이 결과를 보면 아래와 같습니다.
b'modelno,name,price,weight\r\nAGH1341,Laptop,1300000,1200\r\nSOE1029,Desktop,1800000,3500\r\nMSO6503,Keyboard,150000,800\r\nOSW3961,Monitor,380000,1800\r\n'
이게 대체 뭘까요?
잘 보면 맨 앞에 b라는 글자가 써져있고 그 후로 여러 데이터가 따옴표(') 안에 담겨있습니다.
그리고 중간에 보면 \r\n이라는 줄바꿈 기호도 있습니다.
(\n은 줄바꿈 기호인데 \r은 좀 생소하실 수도 있을 것 같습니다. \r에 관련한 설명은 본 글 맨 아래쪽에 적어두겠습니다.)
위 데이터는 csv 데이터를 bytes format으로 나타낸 것입니다.
위 데이터를 csv format으로 변경하여 표로 나타내보면 아래와 같습니다.
modelno | name | price | weight |
AGH1341 | Laptop | 1300000 | 1200 |
SOE1029 | Desktop | 1800000 | 3500 |
MSO6503 | Keyboard | 150000 | 800 |
OSW3961 | Monitor | 380000 | 1800 |
이렇게 보니 무슨 데이터인지 이해가 가시죠?
몇 가지 전자제품의 모델넘버와 이름, 가격, 무게를 나타낸 csv 데이터인 것입니다.
위 데이터를 bytes라는 format으로 나타낸게 바로 아래와 같다는 것이죠.
b'modelno,name,price,weight\r\nAGH1341,Laptop,1300000,1200\r\nSOE1029,Desktop,1800000,3500\r\nMSO6503,Keyboard,150000,800\r\nOSW3961,Monitor,380000,1800\r\n'
3. type(response.content)
그래서 content의 type을 출력했을 때 <class 'bytes'> 라고 출력됩니다.
content의 type이 bytes 타입이라는 것이죠.
보통 API로부터 csv format의 데이터를 얻어올 때 이러한 bytes type의 데이터를 받게 됩니다.
이제 API로부터 데이터를 얻어오는 건 알겠는데 이제 저걸 어떻게 이용할까요?
b'modelno,name,price,weight\r\nAGH1341,Laptop,1300000,1200\r\nSOE1029,Desktop,1800000,3500\r\nMSO6503,Keyboard,150000,800\r\nOSW3961,Monitor,380000,1800\r\n'
위같은 상태로는 위 데이터를 가지고 여러 가지 추가적인 작업을 하려고 해도 어려울 것입니다.
그래서 위 데이터를 pandas의 DataFrame으로 바꾸는 방법을 알아보겠습니다.
import requests
import pandas as pd
from io import BytesIO
api_endpoint = 'https://test_api/get_data'
response = requests.get(api_endpoint)
csv_file = BytesIO(response.content)
df_result = pd.read_csv(csv_file)
print(type(csv_file))
print(df_result)
-- Result
<_io.BytesIO object at 1X11111111>
modelno name price weight
0 AGH1341 Laptop 1300000 1200
1 SOE1029 Desktop 1800000 3500
2 MSO6503 Keyboard 150000 800
3 OSW3961 Monitor 380000 1800
위 코드는 API로부터 얻은 bytes type의 데이터를 pd.read_csv() method를 이용해서 pandas로 바꾸는 예시입니다.
- csv_file = BytesIO(response.content)
위 부분을 보시면 BytesIO라는 새로운 method가 생겼습니다.
io library의 BytesIO method는 bytes type의 csv 데이터를 마치 csv file과 비슷한 형태의 데이터로 바꿔주는 역할을 합니다.
response.content에는 API로부터 받아온 csv 데이터가 bytes type으로 바뀐 형태의 정보가 담겨있습니다.
결국 bytes type의 데이터라는 것이죠.
BytesIO는 이 bytes type의 데이터를 csv file과 같은 형태의 데이털 바꿔줍니다.
그래서 csv_file 변수에 저장된 값의 type을 출력해보면 <_io.BytesIO object at 1X11111111> 이러한 문구가 출력됩니다.
뭔가 data type이 BytesIO object로 바뀌었죠. byets type의 데이터가 csv 파일과 같은 형태로 바뀌었다는 내용으로 받아들이면 됩니다.
- df_result = pd.read_csv(csv_file)
read_csv() method를 이용해서 데이터를 읽어옵니다.
그러면 df_result 변수에 API로부터 받아온 bytes type의 데이터가 DataFrame으로 변환되어 저장됩니다.
modelno | name | price | weight |
AGH1341 | Laptop | 1300000 | 1200 |
SOE1029 | Desktop | 1800000 | 3500 |
MSO6503 | Keyboard | 150000 | 800 |
OSW3961 | Monitor | 380000 | 1800 |
출력된 결과와 위 표를 비교해보면 원하는 데이터가 DataFrame으로 잘 변환된 것을 알 수 있죠.
- 참고
\r은 줄이 바뀔 때 커서를 처음으로 옮기는 것을 의미합니다.
예전에 타자기라는게 있었죠. 자판이 있는 기계에 종이를 꽂아주고 자판을 치면 종이가 왼쪽으로 움직이면서 글씨를 찍어내는 기계요.
여기서 한 줄을 다 쓰고 뭔가를 누르면 종이가 다시 오른쪽으로 쭉 움직이면서 글자가 입력되는 포지션이 다음 줄 맨 앞으로 움직이는 것을 영화같은 데에서 본 적이 있을겁니다.
\r 기호는 마치 위 타자기에서처럼 한 줄이 끝나고 다음 줄로 옮겨갈 때 커서를 맨 처음으로 옮긴다는 의미입니다.
그래서 본 글에서 알아본 bytes type data 등 컴퓨터에서 데이터를 나타낼 때 \r\n을 같이 씁니다.
\r은 커서를 맨 처음으로 옮긴다는 의미이고 \n은 줄바꿈을 의미하므로, 커서를 먼저 맨 처음으로 옮기고 줄을 바꾼다는 의미입니다. 결국 줄바꿈하고 다음 줄의 가장 처음 위치의 커서로 옮겨가겠다는 의미죠.