728x90
728x170
데이터 타입과 입출력
- 판다스에서 제공하는 함수들을 이용해 직접 데이터를 읽고 출력할 수 있다.
- 판다스에서 데이터를 입력하고 출력하는 함수들의 세트를 I/O API 라고 한다.
- 판다스 I/O API를 이용해 다루는 데이터 타입은 텍스트 파일, 이진 데이터 그리고 SQL인 데이터베이스가 있다.
형식 | 데이터 타입 | 읽기 함수 | 쓰기 함수 |
텍스트 | CSV | read_csv | to_csv |
JSON | read_json | to_json | |
HTML | read_html | to_html | |
Local Clipboard | read_clipboard | to_clipboard | |
이진 데이터 | MS 액셀 | read_excel | to_excel |
HDF5 | read_hdf | to_hdf | |
Feather | read_feather | to_feather | |
Parquet | read_parquet | to_parquet | |
Msgpack | read_msgpack | to_msgpack | |
Stata | read_stata | tp_stata | |
SAS | read_sas | ||
Python Pickle | read_pickle | to_pickle | |
SQL | SQL | read_sql | to_sql |
Google Big Query | read_gbq | to_gbq |
텍스트 파일
- 판다스는 다양한 형식의 텍스트 파일을 판다스 객체로 읽고, 텍스트 파일로 쓰는 데 탁월한 기능을 제공한다.
- 텍스트 파일은 콤마(,), 탭(\t), 세미콜론(;), 버티컬 바(|)나 공백(스페이스)으로 데이터 요소를 구분한 형태이다.
- 이 구분자를 기준으로 데이터를 처리한다.
① CSV 파일
- Comma-Separated Values
- 액셀과 같은 테이블형 데이터로 구성되는데, 열 구분에는 콤마를 사용하고, 행 구분에는 <Enter> 키 같은 줄 바꿈을 사용한다.
- 읽을 때 read_csv() 함수를, 쓸 때 to_csv() 함수를 사용한다.
data = {'name': ['haena', 'naeun', 'una', 'bum', 'suho'], 'age': [30, 27, 28, 23, 18],
'address': ['dogok', 'suwon', 'mapo', 'ilsan', 'yeoyi'], 'grade': ['A', 'B', 'C', 'B', 'A'],
'score': [100, 88, 73, 83, 95]}
df = pd.DataFrame(data, columns=['name', 'age', 'address', 'score', 'grade'])
df
- to_csv() 메소드를 사용하면 원하는 디렉터리에 CSV 파일을 생성하고 저장할 수 있다.
df.to_csv('student_grade.csv')
- 주피터 노트북이 실행되는 디렉터리나 파이썬 프로세스가 실행되는 곳을 CWD(Current Working Directory)라고 하는데, read_csv() 함수를 사용하면 파이썬은 이곳에 텍스트 파일이 있는지 찾는다.
>>> !type student_grade.csv
,name,age,address,score,grade
0,haena,30,dogok,100,A
1,naeun,27,suwon,88,B
2,una,28,mapo,73,C
3,bum,23,ilsan,83,B
4,suho,18,yeoyi,95,A
- read_csv() 메소드를 이용해 CSV 파일의 내용을 데이터프레임으로 읽는다.
df1=pd.read_csv('student_grade.csv')
df1
- 불필요한 열 Unnamd: 0을 제거하여 정리한다.
df1 = df1.iloc[0:5, 1:6]
df1
- read_csv() 메소드의 nrows와 header 인수를 사용해 특정 행만 읽고, 헤더의 표시 유무를 결정할 수 있다.
df.to_csv('student_grade.csv')
df2 = pd.read_csv('student_grade.csv', header=None, nrows=3)
df2
- index_col=0 을 인수로 전달해 첫 번째 열인 Unnamed: 0을 제거하여 정리한다.
- 열 레벨이 index_col 의 값이면 인덱스로 전환되어 처리된다.
df2 = pd.read_csv('student_grade.csv', index_col=0)
df2
df2 = pd.read_csv('student_grade.csv', index_col=['name'])
df2
- names 인수에 열 이름을 전달해 CSV 파일을 읽으면, 기존 열 라벨이 첫 번째 행의 데이터 요소가 된다.
df2 = pd.read_csv('student_grade.csv', names=['No', 'name', 'age', 'address', 'score', 'grade'], nrows=3)
df2
- 다음과 같이 인수 na_values 에 열의 특정 위치를 딕셔너리 형태로 전달하여 특정 값을 NaN으로 지정하거나 NaN을 지정한 값으로 변경할 수 있다.
to_na = {'address': ['mapo', 'NA'], 'score': [83]}
df2 = pd.read_csv('student_grade.csv', na_values=to_na)
df2
- skiprows 에 행들을 명시하면 가장 위의 인덱스 라벨을 건너뛰어 출력한다.
- skiprows=3 이면 맨 위의 행 라벨부터 3행을 제외하고 나머지 행을 출력한다.
df2 = pd.read_csv('student_grade.csv', skiprows=3)
df2
>>> !type student_grade1.csv
name|age|address|score|grade
haena|30|dogok|100|A
naeun|27|suwon|88|B
una|28|mapo|73|C
bum|23|ilsan|83|B
suho|18|yeoyi|95|A
- sep 옵션으로 불러올 CSV 파일의 구분자를 지정할 수 있다.
pd.read_csv('student_grade1.csv', sep='|') # 구분자를 | 로 설정하여 불러온다.
② JSON 파일
- JavaScript Object Notation
- 인터넷 웹 브라우저가 서버와 통신할 때 사용하는 표준 데이터타입 중 하나
- 자바스크립트 프로그래밍 언어의 서브세트로써, 가볍고 사용하기 쉽다.
- JSON 형식 파일이나 문자열을 사용할 때는 시리즈나 데이터프레임을 유효한 JSON 문자열로 변환하고 매개 변수와 함께 to_json() 메소드를 실행한다.
- 이때 객체 타입은 str 이다.
- 시리즈나 데이터프레임을 JSON 문자열로 변환하는 여러 방법이 있으며, 매개 변수 orient에 그 값을 설정한다.
- orient='split' 이면 {'index'→[index], 'columns'→[columns], 'data'→[values]} 와 같은 딕셔너리형이 된다.
>>> dfj = pd.DataFrame([[ 'a', 'b'], ['c', 'd']], index=['row1', 'row2'], columns=['col1', 'col2'])
>>> dfj.to_json()
'{"col1":{"row1":"a","row2":"c"},"col2":{"row1":"b","row2":"d"}}'
>>> dfj.to_json(orient='split')
'{"columns":["col1","col2"],"index":["row1","row2"],"data":[["a","b"],["c","d"]]}'
- orient='records' 는 [{column→value}, ..., {column→value}] 와 같은 리스트형이다.
- orient='index' 로 설정하면 {index→{column→value}} 와 같은 딕셔너리형이 된다.
>>> dfj.to_json(orient='records')
'[{"col1":"a","col2":"b"},{"col1":"c","col2":"d"}]'
>>> dfj.to_json(orient='index')
'{"row1":{"col1":"a","col2":"b"},"row2":{"col1":"c","col2":"d"}}'
- orient='columns' 를 입력하면 {column→{index→value}} 같은 딕셔너리형이 되며, orient='values' 는 values 의 배열이다.
>>> dfj.to_json(orient='columns')
'{"col1":{"row1":"a","row2":"c"},"col2":{"row1":"b","row2":"d"}}'
>>> dfj.to_json(orient='values')
'[["a","b"],["c","d"]]'
- orient='table' 은 {'schema': {schema}, 'data': {data}} 와 같이 데이터를 설명하는 딕셔너리형으로써 데이터 요소는 orient='records' 를 입력한 것과 같다.
>>> dfj.to_json(orient='table')
'{"schema":{"fields":[{"name":"index","type":"string"},{"name":"col1","type":"string"},{"name":"col2","type":"string"}],"primaryKey":["index"],"pandas_version":"0.20.0"},"data":[{"index":"row1","col1":"a","col2":"b"},{"index":"row2","col1":"c","col2":"d"}]}'
- JSON 파일도 생성하고 저장할 수 있다.
>>> df = pd.DataFrame(data, columns=['name', 'age', 'address', 'score', 'grade'])
>>> df.to_json('student_grade.json')
- read_json() 함수를 사용해 저장한 JSON 문자열 파일을 읽는다.
pd.read_json('student_grade.json')
- 주피터 노트북이 실행되는 디렉터리나 파이썬 프로세스가 실행되는 CWD에 JSON 파일을 생성하고 읽어본다.
df = pd.DataFrame({'ha': [1, 2, 3, 4], 'hi': ['a', 'b', 'c', 'd'],
'ho': pd.date_range('2021-09-01', freq='d', periods=4),
'hu': pd.Categorical(['a', 'b', 'c', 'd'])}, index=pd.Index(range(4), name='ind'))
df
>>> df.dtypes
ha int64
hi object
ho datetime64[ns]
hu category
dtype: object
- hello.json 이라는 파일을 CWD에 저장하고 저장한 파일을 읽는다.
df.to_json('hello.json', orient='table')
dfj = pd.read_json('hello.json', orient='table')
dfj
>>> dfj.dtypes
ha int64
hi object
ho datetime64[ns]
hu category
dtype: object
③ HTML 파일
- Hyper Text Markup Language
- HTML을 읽을 때 사용하는 read_html() 메소드는 HTML 문자열/파일/URL을 읽고 HTML 테이블을 판다스 데이터프레임의 리스트로 파싱한다.
- 이 함수는 테이블 태그인 <table> 요소와 관련되는 태그 요소들만 검색하고 리스트를 반환한다.
>>> url = 'https://finance.yahoo.com/quote/NNOX/profile?p=NNOX'
>>> dfh = pd.read_html(url)
>>> dfh
[ Name Title Pay Exercised \
0 Mr. Ran Poliakine Founder, Chairman & CEO NaN NaN
1 Mr. Itzhak Maayan Chief Financial Officer NaN NaN
2 Mr. James M. Dara Chief Operating Officer NaN NaN
3 Mr. Ofir Koren Chief Technology Officer NaN NaN
4 Mr. Tal Shank VP of Corp. Devel. NaN NaN
5 Ms. Anat Kaphan VP of Product Marketing NaN NaN
6 Ms. Tamar Aharon Cohen Chief Marketing Officer NaN NaN
7 Ms. Shirly Kaufman-Kirshenbaum VP of HR NaN NaN
8 Mr. Gilad Yron Chief Bus. Officer NaN NaN
9 Ms. Lydia Edwards Pres of Nanox US NaN NaN
Year Born
0 1968.0
1 1966.0
2 1970.0
3 1970.0
4 1978.0
5 1970.0
6 1977.0
7 1975.0
8 1973.0
9 NaN ]
df = pd.DataFrame(np.random.randn(2, 2))
df
- 다음과 같이 to_html() 을 실행하면 HTML 태그가 덧붙여진 테이블을 나타내는 웹 프로그램을 만든다.
- 생성된 HTML 웹 프로그램을 Windows 메모장에 붙여넣고, hello.html 이라는 파일명으로 저장한 후 인터넷 브라우저를 통해 확인하면 결과를 확인할 수 있다.
>>> print(df.to_html())
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>0</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1.098443</td>
<td>-3.070569</td>
</tr>
<tr>
<th>1</th>
<td>0.206129</td>
<td>0.921344</td>
</tr>
</tbody>
</table>
④ 클립 보드
- 클립 보드(Clipboard) : 컴퓨터에서 [Ctrl]+[C] 키를 이용한 복사하기와 [Ctrl]+[V]를 이용한 붙여넣기 등을 사용하기 위해 확보된 임시 저장 공간
- read_clipboard() 메소드를 사용하면 이 데이터를 간단히 읽을 수 있다.
- 클립보드에서 텍스트를 읽어 read_csv() 메소드로 전달한다.
- to_clipboard() 메소드는 객체를 시스템 클립보드로 복사한다.
- 객체의 텍스트 표현을 시스템 클립보드에 쓰거나 액셀에 붙일 수도 있다.
df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=['A', 'B', 'C'])
df.to_clipboard(sep=',', index=False)
pd.read_clipboard()
이진 데이터
- 0과 1, 두 개의 상태로만 구성되는 형식의 데이터
- 액셀, HDF5(Hierarchical Data Format Version 5), SAS(Statistical Analysis Software) 및 파이썬 Pickle 모듈 등에서 사용된다.
① 액셀 파일
- read_excel() 메소드는 액셀 파일에서 데이터를 추출하는 파이썬 라이브러리인 xlrd 모듈을 이용해 확장자가 xls, xlsx 인 액셀 파일을 불러온다.
- to_excel() 메소드를 사용하면 데이터프레임을 액셀로 저장할 수 있다.
예제 : 2018년도 전국 상가 업력 현황
>>> df1 = pd.read_excel('shoppingcenter.xlsx')
>>> df2 = pd.read_excel('shoppingcenter.xlsx')
>>> df = pd.read_excel('shoppingcenter.xlsx')
df
- 2개 시트로 구성된 액셀 파일을 실행한 결과 기본으로 첫 번째 시트인 '2018년 상반기 업력현황' 내용만을 나타낸다.
df1 = pd.read_excel('shoppingcenter.xlsx', sheet_name='2018년 하반기 업력현황')
df1
- 다음과 같이 sheet_name=None 옵션을 사용하면 2018년 상반기와 하반기 업력 현황 시트를 한 꺼번에 읽을 수 있다.
df.to_excel('file_with_path.xlsx', sheet_name='Sheet1')
- 데이터프레임 객체를 액셀 파일의 시트에 쓰려면 to_excel() 메소드를 사용한다.
- to_csv() 메소드에서 사용하는 인수들을 to_excel() 메소드에도 적용할 수 있다.
② HDF5 파일
- 매우 크고 복잡한 이종(Heterogeneous) 데이터를 지원하는 오픈 소스 파일 형식
- 진화하는 컴퓨팅 및 저장 환경에서 다양하고 복잡한 데이터를 조작, 저장, 탐색, 접근, 분석 그리고 보전하기 위해 설계되었다.
- 인공위성의 원격 센싱 데이터, 원자력 시험 모델 데이터, 고해상도 MRI 뇌 스캔 데이터 등 디지털로 저장된 모든 형태의 이진 데이터는 HDF5 파일로 저장하고 관리할 수 있다.
- 특징
- 데이터를 관리하고 저장하기 위한 모델 구현
- 데이터 객체의 수나 크기에 제한이 없는 완전한 이식성(Portable)을 제공하는 파일 형식
- PC부터 대용량 병렬 시스템까지 다양한 연산 플랫폼에서 실행되는 소프트웨어 라이브러리
- C, C++, 포트란 90 및 Java 인터페이스에서 고차원 API를 실행하는 소프트웨어 라이브러리
- 디렉터리 접속을 빠르게 하고, 저장 공간을 최적화하는 헤더와 데이터 배열로 이루어진 데이터 세트
- 데이터를 관리, 조작, 시각화 및 분석하기 위한 도구 및 애플리케이션
- pandas.io.pytables.HDFStore 클래스는 PyTables 라이브러리를 사용해 고성능 HDP5 파일을 읽고 쓸 수 있도록 하는 유사 딕셔너리 객체이다.
>>> hfs = pd.HDFStore('store.h5')
>>> hfs
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
- HDFStore 객체인 데이터프레임을 생성하는 데 필요한 객체를 다음과 같이 생성한다.
>>> ind = pd.date_range('1/1/2021', periods=8)
>>> ser = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
>>> df = pd.DataFrame(np.random.randn(8, 3), index=ind, columns=['A', 'B', 'C'])
>>> country = ['KOR', 'US', 'ITALY']
>>> mind = pd.MultiIndex.from_product([country, ind])
>>> col = ["item_%d" % i for i in range(1, 4)]
>>> data = np.random.randn(24, 3)
- 데이터프레임 객체 df1을 생성하고 내용을 확인한다.
df1 = pd.DataFrame(data, index=mind, columns=col)
df1
- HDFStore 객체인 hfs에 ser, df, df1을 동적 할당한다.
>>> hfs['ser'] = ser
>>> hfs['df'] = df
>>> hfs['df1'] = df1
>>> hfs
<class 'pandas.io.pytables.HDFStore'>
File path: store.h5
- HDFStore 객체인 hfs에 저장된 데이터프레임 객체 df는 다음과 같이 확인할 수 있다.
hfs['df']
더보기
- 결과는 hfs.df나 hfs.get('df')를 사용한 결고와 같으며, 파일에 저장된 판다스 객체를 반환한다.
- del 명령어에 객체 이름인 df1을 키로 사용하면 df1 객체를 삭제할 수 있다.
- hfs.remove("df1") 을 실행해도 다음과 같은 결과가 나타난다.
- 파일을 닫으려면 close() 를 적용한다.
>>> del hfs['df1']
>>> hfs['df1']
KeyError: 'No object named df1 in the file'
>>> hfs.close()
>>> hfs['ser'] # hfs.df
ClosedFileError: store.h5 file is not open!
- HDFStore는 HDF5 파일을 읽고 쓰기 위해 read_hdf(), to_hdf() 메소드를 사용하는 API를 지원한다.
- 데이터프레임 객체의 to_hdf() 메소드는 HDFStore를 이용해 데이터를 HDF5 파일에 쓴다.
df_s = pd.DataFrame({'A': list(range(5)), 'B': list(range(5))})
df_s.to_hdf('hfs_s.h5', 'table', append=True)
pd.read_hdf('hfs_s.h5', 'table', where=['index>2'])
SQL 데이터베이스
- pandas.io.sql 모듈은 데이터를 쉽게 검색할 수 있게 한다.
- 또한, 특정 DB API에 대한 의존성을 낮추기 위해 질의어 래퍼(Query Wrapper)를 제공한다.
- 데이터베이스를 운용하려면 드라이버가 필요하며, PostgreSQL 데이터베이스 운용에는 psycopg2, MySQL 응용에는 pymysql 드라이버가 필요하다.
- 파이썬 표준 라이브러리에는 SQLite가 기본으로 포함된다.
SQLAlchemy의 엔진 구성
SQLAlchemy
- 애플리케이션 개발을 위해 SQL의 유연성과 강력한 기능을 제공하는 파이썬의 SQL 툴킷(toolkit) 및 ORM(Object Relational Mapping, 객체 관계 매핑)
- ORM(Object Relational Mapping, 객체 관계 매핑)
- 객체 지향 프로그래밍 언어와 호환할 수 없는 시스템 사이에서 데이터를 변환하는 프로그래밍 기술
- 애플리케이션 코드에서 공통적으로 사용되는 객체들로써, 관계형 데이터베이스 테이블들에 저장된 데이터의 이동을 자동화하는 코드 라이브러리
- ORM(Object Relational Mapping, 객체 관계 매핑)
- MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Firebird, Sybase 등 다양한 타입의 데이터베이스인 방언(Dialect)들이 소통하도록 한다.
- 파이썬에서는 SQLite 또는 SQLAlchemy를 임포트하여 SQL 데이터베이스를 관리하고 연산할 수 있다.
엔진(Engine)
- SQLAlchemy 응용을 위한 시작점
- 실제 데이터베이스와 DBAPI에서 홈 베이스 같은 역할을 한다.
- DBAPI
- 'Python Database API Specification' 의 줄임말
- 모든 데이터베이스 연결 패키지에 공통 사용 패턴을 정의하기 위해 파이썬 내에서 널리 사용되는 규격
- DBAPI
- 파이썬 애플리케이션이 데이터베이스와 대화하기 위해 사용하는 가장 낮은 수준의 시스템인 저수준 API
- 저수준 : 응용 레벨이 아닌 시스템 속성에 해당하는 레벨
- SQLAlchemy의 방언은 다양한 형태의 DBAPI를 구현하고, 데이터베이스와 통신하기 위해 SQLAlchemy가 사용하는 시스템이다.
- 엔진은 연결 풀(Pool)과 방언을 통해 SQLAlchemy 애플리케이션이 전달되고, 특정 종류의 database/DBAPI 조합과 대화하는 방법을 설정한다.
- 방언과 풀은 데이터베이스의 형태와 DBAPI 모듈 기능을 해석하며, 엔진은 이들을 참조한다.
- create_engine() 으로 엔진을 생성할 수 있으며, 엔진은 개개로 이루어진 많은 DBAPI 연결을 관리한다.
from sqlalchemy import create_engine
engine = create_engine('postgresql://scott:tiger@localhost:5432/mydb')
SQLite
- 파이썬에 기본으로 내장된 sqlite3 모듈을 사용하여 파일 기반의 데이터베이스에 연결한다.
- SQLite가 로컬 파일에 연결될 때 사용되는 URL 형식은 기존에 파일과 연결할 때 사용하던 URL 형식과 조금 다르다.
- URL의 파일 부분은 데이터베이스의 파일명이다.
- sqlite3 모듈을 사용해 엔진이 생성되는 곳을 기준으로 하는 상대적 파일 경로를 설정할 때, 다음과 같이 슬래시 3개 다음 파일명이 위치한다.
# sqlite://<nohostname>/<path>
# where <path> is relative:
engine = create_engine('sqlite:///jin.db')
- 절대 파일 경로를 입력할 때는 슬래시 3개 다음 절대 경로가 위치한다.
# windows
engine = create_engine('sqlite:///C:\\path\\to\\jin.db')
# windows alternative using raw string
engine = create_engne(r'sqlite:///C:\path\to\jin.db')
# Unix/Mac - 4 initial slashes in total
engine = create_engne('sqlite:///absolute/path/to/jin.db')
- SQLite 데이터베이스가 단일 디스크 파일이 아닌 메모리에 저장하는 SQLite :memory:database 를 명시할 때는 다음과 같이 2가지 형태를 사용할 수 있다.
- 파일명은 :memory: 와 같다.
engine = create_engine('sqlite://')
engine = create_engine('sqlite:///:memory:')
판다스 SQL 관련 함수 적용
- 판다스에서 제공하는 SQL 관련 주요 함수는 다음과 같다.
종류 | 기능 |
read_sql_table | SQL 데이터베이스 테이블을 데이터프레임으로 읽는다. |
read_sql_query | SQL 쿼리를 데이터프레임으로 읽는다. |
read_sql | SQL 쿼리 또는 데이터베이스 테이블을 데이터프레임으로 읽는다. |
DataFrame.to_sql | 데이터프레임에 저장된 레코드를 SQL 데이터베이스로 쓴다. |
- SQLAlchemy에 연결하기 위해 데이터베이스 URI에서 engine 객체를 생성하는 create_engine() 함수를 사용한다.
- SQLAlchemy에 연결할 때, 하나의 데이터베이스마다 엔진을 한 번씨 생성해야 한다.
- SQLite 데이터베이스는 보통 하나의 디스크 파일에 저장되지만, 메모리에 저장되는 경우도 있다.
- SQLite 데이터베이스를 메모리에 상주하도록 하는 보편적인 방법은 특수한 파일명인 ':memory:' 를 사용해 데이터베이스를 여는 것이다.
# SQLite SQL 데이터베이스 엔진을 사용하며, 데이터가 메모리에 저장되는 임시 SQLite 데이터베이스를 사용한다.
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:')
- 먼저 to_sql() 함수를 이용해 데이터프레임의 데이터를 데이터베이스에 저장한다.
- 크기가 매우 큰 데이터를 포함하는 데이터프레임을 데이터베이스에 저장하는 경우, 패킷 크기 제한으로 인해 오류가 발생할 수 있다.
- 이때는 chunksize 인수를 실행해 청크(Chunk) 크기를 제한한다.
- 청크(Chunk) : 데이터를 일정 크기로 쪼갠 덩어리
- 이때는 chunksize 인수를 실행해 청크(Chunk) 크기를 제한한다.
df2.to_sql('data_db', engine)
df2.to_sql('data_db1', engine, chunksize=1000)
- red_sql_table() 에 테이블 이름과 읽을 열의 서브세트를 옵션으로 지정하면 데이터베이스 테이블을 읽는다.
pd.read_sql_table('data_db', engine)
- 다음과 같이 인덱스를 이용해 행의 이름을 데이터프레임의 인덱스로 지정하고, 열의 서브세트를 설정해 일부 열만 읽을 수도 있다.
pd.read_sql_table('data_db', engine, index_col='name')
pd.read_sql_table('data_db', engine, columns=['name', 'grade'])
- read_sql_query() 함수에 원시 SQL을 사용하여 질의할 수 있다.
- 이때 read_sql_query() 인수로 데이터베이스에 적합한 sql_variant 타입을 사용해야 한다.
pd.read_sql_query('SELECT * FROM data_db', engine)
- 다음은 grade가 A인 name과 address를 검색하는 조건을 부여해 질의한 예제이다.
pd.read_sql_query("SELECT name, address FROM data_db WHERE grade='A';", engine)
- read_sql_query() 함수는 chunksize 인수를 지원한다.
- chunksize 인수의 기능을 살펴보기 위해 먼저 다음과 같이 데이터프레임을 생성하고 데이터베이스에 저장한다.
dfc = pd.DataFrame(np.random.randn(9, 3), columns=list('abc'))
dfc.to_sql('data_ck', engine, index=False)
- chunksize를 인수로 전달하면 질의 결과에 청크가 적용된 이터레이터를 반환한다.
>>> for chunk in pd.read_sql_query("SELECT * FROM data_ck", engine, chunksize=3):
>>> print(chunk)
a b c
0 -0.733973 -0.919681 -0.116925
1 0.351232 -0.376313 -0.983268
2 -0.199314 -1.068167 -0.264015
a b c
0 0.230098 0.676113 -0.046839
1 0.129894 0.307725 0.971459
2 1.460186 1.152541 -0.906164
a b c
0 1.872970 0.699920 -1.106343
1 0.545566 1.396238 -1.129041
2 -0.451837 0.448178 -0.203647
sqlite3
- SQLAlchemy를 사용하지 않고 파이썬 내장 드라이버로 지원된다.
- 파이썬 DBAPI를 준수하는 파이썬 데이터베이스 어댑터를 요구한다.
sqlite3 연결을 설정하고 데이터베이스가 메모리에 저장되도록 설정한 후, 쿼리를 통해 조회할 수 있도록 하는 절차
import sqlite3
con = sqlite3.connect(':memory:')
data.to_sql('data', con)
pd.read_sql_query("SELECT * FROM data", con)
기상청 대용량 데이터 세트의 처리
- 수십 GB 이상인 대용량 데이터 파일을 이용해 작업할 때, 컴퓨터와 제한된 RAM 용량 때문에 작업이 수월하지 않은 경우가 있다.
- 판다스는 이를 해결할 여러 방법을 제시한다.
- 중요하지 않는 데이터를 삭제하거나 int64를 int32로 변경하는 dtype 매개 변수를 사용하는 등 데이터 요소 타입을 변경할 수 있다.
- 파일 크기를 쪼개 처리하고 분석할 수 있는 chunk 옵션을 적용할 수 있다.
- chunk 옵션
- 핵심 기능 : 메모리 사용을 효과적으로 줄이는 것
- read_csv() 의 chunksize 매개 변수를 이용한다.
- 대용량 텍스트 파일을 데이터프레임으로 읽을 때 일정한 크기로 나누어 처리한다.
예제 : 기상청 데이터 처리
- 우리나라 기상청에서 대기를 3개 항목을 기준으로 측정한 예제 데이터
- 291,600 행으로 이루어져 있다.
- 용량 : 3.5MB
- 기상청에서 산출되는 엄청난 규모의 데이터는 컴퓨팅 메모리에 기준 이상의 과부하를 발생시켜 실행이 어려울 수 있다.
- 이를 방지하기 위해 chunksize 를 적용한다.
df = pd.read_csv('air_test.csv')
df
- 이 파일을 나누어 처리하기 위해 chunksize를 10,000으로 전달해 실행하면 291,600행을 10,000행으로 이루어진 29개의 청크와 1,600행으로 이루어진 1개 청크, 총 30개의 청크로 처리한다.
>>> df_chunk = pd.read_csv('air_test.csv', chunksize=10000)
>>> df_chunk
<pandas.io.parsers.TextFileReader at 0x2171db746a0>
- chunksize 의 매개 변수로 처리한 연산 결과인 df_chunk는 DataFrame 객체가 아닌 TextFileReader 객체이다.
- TextFileReader 객체는 반복 처리를 할 수 있다.
- 이는 청크 단위로 연산하여 그 결과를 결합해 DataFrame 객체를 산출하는 원리이다.
- 이를 확인하기 위해 다음과 같이 실행한다.
for chunk in df_chunk:
print(chunk)
더보기
site_code test_no average
0 104 1 0.008
1 102 8 101.000
2 102 9 64.000
3 102 6 0.071
4 102 1 0.005
... ... ... ...
9995 107 3 0.065
9996 125 9 98.000
9997 125 8 137.000
9998 125 6 0.029
9999 125 5 0.900
[10000 rows x 3 columns]
site_code test_no average
10000 125 1 0.005
10001 125 3 0.050
10002 109 9 84.000
10003 109 8 114.000
10004 109 6 0.026
... ... ... ...
19995 106 6 0.005
19996 106 5 0.800
19997 106 1 0.005
19998 106 3 0.058
19999 110 9 38.000
[10000 rows x 3 columns]
site_code test_no average
20000 110 8 51.000
20001 110 6 0.005
20002 110 5 0.700
20003 110 1 0.008
20004 110 3 0.037
... ... ... ...
29995 102 5 0.900
29996 102 3 0.059
29997 102 1 0.006
29998 102 6 0.011
29999 102 9 41.000
[10000 rows x 3 columns]
site_code test_no average
30000 117 8 71.000
30001 122 9 36.000
30002 122 8 50.000
30003 122 6 0.005
30004 122 5 0.700
... ... ... ...
39995 107 3 0.058
39996 125 9 65.000
39997 125 8 73.000
39998 125 6 0.022
39999 125 5 0.800
[10000 rows x 3 columns]
site_code test_no average
40000 125 1 0.006
40001 125 3 0.046
40002 109 9 63.000
40003 109 8 73.000
40004 109 6 0.025
... ... ... ...
49995 102 8 42.000
49996 122 9 24.000
49997 122 8 43.000
49998 122 6 0.005
49999 122 5 0.300
[10000 rows x 3 columns]
site_code test_no average
50000 122 1 0.004
50001 122 3 0.052
50002 105 9 33.000
50003 105 8 46.000
50004 105 6 0.007
... ... ... ...
59995 117 9 32.000
59996 117 8 41.000
59997 117 6 0.035
59998 117 5 0.400
59999 117 1 0.004
[10000 rows x 3 columns]
site_code test_no average
60000 118 9 33.000
60001 122 9 29.000
60002 122 8 34.000
60003 122 6 0.032
60004 122 5 0.400
... ... ... ...
69995 102 3 0.049
69996 102 1 0.004
69997 102 6 0.005
69998 102 9 22.000
69999 102 8 40.000
[10000 rows x 3 columns]
site_code test_no average
70000 122 9 17.000
70001 122 8 45.000
70002 122 6 0.006
70003 122 5 0.400
70004 122 1 0.005
... ... ... ...
79995 101 6 0.015
79996 101 5 0.700
79997 101 1 0.004
79998 101 3 0.035
79999 104 9 23.000
[10000 rows x 3 columns]
site_code test_no average
80000 104 8 46.000
80001 104 6 0.023
80002 104 5 0.800
80003 104 1 0.006
80004 104 3 0.021
... ... ... ...
89995 102 5 0.400
89996 102 3 0.017
89997 102 1 0.002
89998 102 6 0.032
89999 102 9 11.000
[10000 rows x 3 columns]
site_code test_no average
90000 115 9 17.000
90001 101 9 15.000
90002 101 8 28.000
90003 101 6 0.029
90004 101 5 0.400
... ... ... ...
99995 119 8 45.000
99996 119 6 0.068
99997 119 5 0.200
99998 119 1 0.004
99999 119 3 0.025
[10000 rows x 3 columns]
site_code test_no average
100000 123 9 19.000
100001 123 8 33.000
100002 123 6 0.005
100003 123 5 0.500
100004 123 1 0.004
... ... ... ...
109995 119 1 0.005
109996 119 3 0.037
109997 123 9 35.000
109998 123 8 40.000
109999 123 6 0.002
[10000 rows x 3 columns]
site_code test_no average
110000 123 5 0.600
110001 123 1 0.007
110002 123 3 0.039
110003 124 9 30.000
110004 110 1 0.008
... ... ... ...
119995 106 3 0.050
119996 115 8 110.000
119997 102 9 40.000
119998 115 9 64.000
119999 102 8 74.000
[10000 rows x 3 columns]
site_code test_no average
120000 118 9 34.000
120001 122 9 36.000
120002 122 8 74.000
120003 122 6 0.003
120004 122 5 1.000
... ... ... ...
129995 124 5 0.400
129996 123 3 0.015
129997 124 9 12.000
129998 124 8 31.000
129999 124 6 0.027
[10000 rows x 3 columns]
site_code test_no average
130000 105 3 0.016
130001 123 9 26.000
130002 123 5 0.400
130003 101 5 0.500
130004 101 3 0.025
... ... ... ...
139995 123 9 24.000
139996 119 5 0.600
139997 123 5 0.600
139998 123 6 0.002
139999 123 8 37.000
[10000 rows x 3 columns]
site_code test_no average
140000 119 6 0.006
140001 124 8 42.000
140002 124 9 20.000
140003 124 6 0.002
140004 123 3 0.055
... ... ... ...
149995 113 6 0.002
149996 113 8 56.000
149997 113 5 1.200
149998 113 9 23.000
149999 109 9 23.000
[10000 rows x 3 columns]
site_code test_no average
150000 110 5 0.700
150001 120 3 0.052
150002 104 1 0.005
150003 104 3 0.040
150004 117 3 0.050
... ... ... ...
159995 104 5 1.300
159996 104 6 0.004
159997 124 5 1.300
159998 107 6 0.002
159999 107 8 107.000
[10000 rows x 3 columns]
site_code test_no average
160000 107 5 1.100
160001 107 9 78.000
160002 107 3 0.057
160003 104 3 0.052
160004 107 1 0.005
... ... ... ...
169995 105 8 47.000
169996 101 1 0.004
169997 111 5 0.600
169998 105 5 0.600
169999 101 5 0.500
[10000 rows x 3 columns]
site_code test_no average
170000 121 3 0.023
170001 105 6 0.018
170002 108 9 18.000
170003 117 6 0.022
170004 117 8 29.000
... ... ... ...
179995 105 6 0.022
179996 109 6 0.026
179997 112 8 147.000
179998 114 5 1.100
179999 114 3 0.043
[10000 rows x 3 columns]
site_code test_no average
180000 106 6 0.025
180001 125 9 68.000
180002 101 6 0.034
180003 119 1 0.004
180004 119 3 0.038
... ... ... ...
189995 109 1 0.007
189996 112 6 0.002
189997 109 3 0.050
189998 112 1 0.004
189999 112 5 0.800
[10000 rows x 3 columns]
site_code test_no average
190000 112 3 0.042
190001 109 8 54.000
190002 109 6 0.002
190003 109 5 0.900
190004 109 9 43.000
... ... ... ...
199995 102 9 17.000
199996 115 5 0.500
199997 120 5 0.400
199998 119 9 19.000
199999 120 9 21.000
[10000 rows x 3 columns]
site_code test_no average
200000 119 6 0.015
200001 119 1 0.005
200002 108 3 0.022
200003 119 8 25.000
200004 123 9 18.000
... ... ... ...
209995 101 6 0.019
209996 122 9 23.000
209997 105 3 0.021
209998 104 8 63.000
209999 104 9 37.000
[10000 rows x 3 columns]
site_code test_no average
210000 102 8 56.000
210001 102 9 33.000
210002 102 6 0.015
210003 102 1 0.005
210004 102 3 0.032
... ... ... ...
219995 117 9 19.000
219996 118 8 44.000
219997 118 9 28.000
219998 118 6 0.019
219999 118 1 0.005
[10000 rows x 3 columns]
site_code test_no average
220000 118 3 0.037
220001 118 5 0.500
220002 114 8 33.000
220003 114 9 22.000
220004 114 6 0.024
... ... ... ...
229995 109 6 0.003
229996 109 8 29.000
229997 109 9 23.000
229998 113 3 0.040
229999 113 1 0.004
[10000 rows x 3 columns]
site_code test_no average
230000 113 5 1.200
230001 113 6 0.003
230002 113 8 35.000
230003 113 9 23.000
230004 107 3 0.043
... ... ... ...
239995 121 8 28.000
239996 122 5 0.200
239997 122 9 2.000
239998 122 6 0.021
239999 122 8 26.000
[10000 rows x 3 columns]
site_code test_no average
240000 110 3 0.013
240001 110 1 0.006
240002 110 5 0.400
240003 110 6 0.018
240004 110 8 22.000
... ... ... ...
249995 119 9 24.000
249996 116 3 0.057
249997 116 1 0.005
249998 116 8 32.000
249999 116 5 0.800
[10000 rows x 3 columns]
site_code test_no average
250000 116 6 0.002
250001 116 9 17.000
250002 111 6 0.002
250003 111 5 0.800
250004 111 1 0.004
... ... ... ...
259995 109 3 0.041
259996 109 1 0.011
259997 109 5 0.900
259998 109 6 0.019
259999 109 8 95.000
[10000 rows x 3 columns]
site_code test_no average
260000 109 9 85.000
260001 103 3 0.045
260002 103 1 0.005
260003 103 5 0.800
260004 103 6 0.017
... ... ... ...
269995 122 9 21.000
269996 105 1 0.015
269997 105 5 1.100
269998 108 8 54.000
269999 105 3 0.050
[10000 rows x 3 columns]
site_code test_no average
270000 102 8 47.000
270001 102 9 27.000
270002 102 1 0.005
270003 102 6 0.002
270004 102 3 0.059
... ... ... ...
279995 107 3 0.042
279996 107 5 0.500
279997 107 1 0.007
279998 107 6 0.002
279999 107 8 42.000
[10000 rows x 3 columns]
site_code test_no average
280000 107 9 32.000
280001 103 3 0.052
280002 103 1 0.004
280003 103 5 0.800
280004 103 6 0.001
... ... ... ...
289995 113 6 0.011
289996 113 8 19.000
289997 113 9 12.000
289998 109 3 0.020
289999 109 1 0.007
[10000 rows x 3 columns]
site_code test_no average
290000 109 5 0.600
290001 109 6 0.017
290002 109 8 21.000
290003 109 9 13.000
290004 125 3 0.036
... ... ... ...
291595 116 3 0.021
291596 116 8 19.000
291597 124 6 0.014
291598 110 9 11.000
291599 116 6 0.025
[1600 rows x 3 columns]
- TextFileReader 객체인 df_chunk를 연산한 chunk의 타입은 DataFrame 객체이다.
- 데이터 크기를 일정하게 나눈 청크들을 차례로 실행하고 나면 포인터가 마지막 청크의 끝을 가리키므로 더 이상 처리할 수 없다.
>>> type(chunk)
pandas.core.frame.DataFrame
>>> ser1 = pd.Series(['a', 'b'])
>>> ser2 = pd.Series(['c', 'd'])
>>> pd.concat([ser1, ser2])
0 a
1 b
0 c
1 d
dtype: object
>>> pd.concat([ser1, ser2], ignore_index=True)
0 a
1 b
2 c
3 d
dtype: object
- df_chunk 를 이어 붙일 때 인덱스를 중복하지 않고 순차적으로 표시하려면 ignore_index=True 를, 인덱스를 중복 표시하려면 기본값인 ignore_index=False 를 입력한다.
pd.concat(df_chunk, ignore_index=True)
728x90
그리드형(광고전용)
'In-depth Study > Pandas' 카테고리의 다른 글
[Pandas] 수학 계산 (0) | 2022.05.31 |
---|---|
[Pandas] 데이터의 그룹 연산 (0) | 2022.05.30 |
[Pandas] 데이터 가공 (0) | 2022.05.29 |
[Pandas] 데이터 처리 (0) | 2022.05.27 |
[Pandas] 판다스의 주요 기능 (0) | 2022.05.25 |
[Pandas] 판다스 데이터 구조 (1) | 2022.05.24 |
[Pandas] 판다스(Pandas) 개요 (0) | 2022.05.24 |