Python io : StringIO (comma separate csv type string 생성, DataFrame을 csv type string으로 변환하기)
아래와 같은 DataFrame이 있다고 생각해봅시다.
import pandas as pd
from io import StringIO
dict_test = {
'id': [1, 2, 3, 4, 5],
'name': ['banana', 'apple', 'melon', 'peach', 'grape'],
'price': [3500, 16000, 15000, 25000, 5800]
}
df_test = pd.DataFrame(dict_test)
print(df_test)
-- Result
id name price
0 1 banana 3500
1 2 apple 16000
2 3 melon 15000
3 4 peach 25000
4 5 grape 5800
만약 위 DataFrame을 comma(,)로 나눠진 csv 형태의 string으로 바꾸려면 어떻게 하면 될까요?
id,name,price
1,banana,3500
2,apple,16000
3,melon,15000
4,peach,25000
5,grape,5800
참고로 comma separate csv type data는 위와 같이 보일겁니다.
각 컬럼이 comma로 구분되어있고, 각 행은 줄바꿈(\n)으로 구분되어있죠.
comma separate csv type data를 얻어내기 위해서는 다양한 방법이 있을 수 있습니다만, 일단 Local에서 위 코드를 실행한다면 to_csv() method를 이용해 csv 파일을 만들고 그 파일을 그대로 읽어올 수도 있습니다.
근데 문제는 만약 sever 상에서 위 코드가 실행되는 경우 csv 파일을 서버의 어느 경로에 만들어두고 그걸 읽어오는 등의 상황이 어려울 수 있습니다. 환경마다 다르겠지만 서버 자체에서 특정 directory에 to_csv() method를 이용해 파일을 만드는 것을 보안 이슈로 막아놓는 등 서버에서는 그 서버의 설정에 따라 파일을 생성하고 읽어오는 것이 자유롭지 않을 수 있습니다.
id,name,price
1,banana,3500
2,apple,16000
3,melon,15000
4,peach,25000
5,grape,5800
이렇게 제약된 상황에서 위 같은 형태의 csv 데이터를 코드 내에서 얻어내야 할 필요가 생길 수 있습니다.
이럴 때 좋은 방법 중 하나는 StringIO를 이용하는 것입니다.
그 원리를 간단하게 말하자면 csv string을 메모리에 저장해두고 사용하는 방식입니다.
I/O는 Input / Output의 약자로 입출력이라는 의미를 가집니다.
대충 해석해보면 StringIO는 String을 Input / Output할 수 있게 해주는 무언가라고 짐작할 수 있겠네요.
StringIO는 메모리에서 String data를 다루고,
BytesIO는 메모리에서 Binary data를 다룰 수 있게 해줍니다.
StringIO, BytesIO는 실제 파일같은 객체를 생성하고 다룰 수 있게 해줍니다.
그래서 파일같은 정보를 다룰 때 유용합니다.
import pandas as pd
from io import StringIO
dict_test = {
'id': [1, 2, 3, 4, 5],
'name': ['banana', 'apple', 'melon', 'peach', 'grape'],
'price': [3500, 16000, 15000, 25000, 5800]
}
df_test = pd.DataFrame(dict_test)
print(df_test)
csv_io = StringIO()
df_test.to_csv(csv_io, index=False)
print(csv_io)
csv_values = csv_io.getvalue()
print(csv_values)
print(type(csv_values))
-- Result
id name price
0 1 banana 3500
1 2 apple 16000
2 3 melon 15000
3 4 peach 25000
4 5 grape 5800
<_io.StringIO object at 0x7f917658a5f0>
id,name,price
1,banana,3500
2,apple,16000
3,melon,15000
4,peach,25000
5,grape,5800
<class 'str'>
위 예시의 결과를 보면 마지막에 comma separate csv type data가 출력된 것을 볼 수 있습니다.
각 코드를 봅시다.
csv_io = StringIO()
df_test.to_csv(csv_io, index=False)
먼저 StringIO() class를 이용하여 csv_io라는 변수에 StringIO() 객체를 하나 생성합니다.
그리고 DataFrame인 df_test에다가 to_csv() method를 이용하여 csv로 만듭니다.
근데 중요한 것은 보통 to_csv() method에서 첫 번째 인자는 csv 파일이 생성될 경로와 파일 이름을 명시하는데, 여기서는 csv_io 객체를 전달했습니다.
이런 경우 csv_io 객체에 DataFrame이 csv로 변환된 후 이 csv에 대한 정보가 StringIO() 객체(csv_io)에 저장됩니다.
csv_values = csv_io.getvalue()
마지막으로 만들어진 csv_io 객체에서 getvalue() method를 이용하면 comma separate csv type data를 얻을 수 있죠.
id,name,price
1,banana,3500
2,apple,16000
3,melon,15000
4,peach,25000
5,grape,5800
<class 'str'>
이로 인해 얻어진 결과는 위와 같고 그 type은 string입니다.