빠른 시작
이 튜토리얼은 PyMongoArrow 작업을 소개하기 위한 것입니다. 이 튜토리얼에서는 독자가 기본 PyMongo 및 MongoDB 개념에 익숙하다고 가정합니다.
전제 조건
PyMongoArrow 배포판 이(가) 설치되어 있는지 확인합니다. Python shell 에서 다음 항목이 예외 없이 실행 되어야 합니다.
import pymongoarrow as pma
또한 이 튜토리얼에서는 MongoDB 인스턴스가 기본 호스트 및 포트에서 실행 중이라고 가정합니다. MongoDB를 다운로드하여 설치 한 후에는 다음 코드 예제와 같이 시작할 수 있습니다.
$ mongod
PyMongo 확장
pymongoarrow.monkey
모듈은 PyMongo를 제자리에 패치하고 PyMongoArrow 기능을 Collection
인스턴스에 직접 추가하는 인터페이스를 제공합니다.
from pymongoarrow.monkey import patch_all patch_all()
monkey.patch_all()
메서드를 실행하면 Collection
클래스의 새 인스턴스에 PyMongoArrow API(예: pymongoarrow.api.find_pandas_all()
메서드)가 포함됩니다.
참고
pymongoarrow.api
모듈에서 PyMongoArrow API를 가져와서 사용할 수도 있습니다. Collection
이 경우 API 메서드를 호출할 때 작업을 실행할 인스턴스를 첫 번째 인수로 전달해야 합니다.
테스트 데이터
다음 코드는 PyMongo를 사용하여 cluster에 샘플 데이터를 추가합니다:
from datetime import datetime from pymongo import MongoClient client = MongoClient() client.db.data.insert_many([ {'_id': 1, 'amount': 21, 'last_updated': datetime(2020, 12, 10, 1, 3, 1), 'account': {'name': 'Customer1', 'account_number': 1}, 'txns': ['A']}, {'_id': 2, 'amount': 16, 'last_updated': datetime(2020, 7, 23, 6, 7, 11), 'account': {'name': 'Customer2', 'account_number': 2}, 'txns': ['A', 'B']}, {'_id': 3, 'amount': 3, 'last_updated': datetime(2021, 3, 10, 18, 43, 9), 'account': {'name': 'Customer3', 'account_number': 3}, 'txns': ['A', 'B', 'C']}, {'_id': 4, 'amount': 0, 'last_updated': datetime(2021, 2, 25, 3, 50, 31), 'account': {'name': 'Customer4', 'account_number': 4}, 'txns': ['A', 'B', 'C', 'D']}])
스키마 정의
PyMongoArrow는 데이터 스키마를 사용하여 쿼리 결과 세트를 표 형식으로 마셜링합니다. 이 스키마를 제공하지 않으면 PyMongoArrow가 데이터에서 스키마를 추론합니다. 다음 예와 같이 Schema
객체를 만들고 필드 이름을 유형 지정자에 매핑하여 스키마를 정의할 수 있습니다.
from pymongoarrow.api import Schema schema = Schema({'_id': int, 'amount': float, 'last_updated': datetime})
MongoDB는 내장된 문서를 사용하여 중첩된 데이터를 표현합니다. PyMongoArrow는 이러한 문서에 대해 최고 수준의 지원을 제공합니다.
schema = Schema({'_id': int, 'amount': float, 'account': { 'name': str, 'account_number': int}})
PyMongoArrow는 목록과 중첩 목록도 지원합니다.
from pyarrow import list_, string schema = Schema({'txns': list_(string())}) polars_df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
팁
PyMongoArrow에는 지원되는 각 BSON types에 대해 여러 개의 허용 가능한 유형 식별자가 포함되어 있습니다. 이러한 데이터 유형과 관련 유형 식별자의 전체 목록은 데이터 유형을 참조하세요 .
작업 찾기
다음 코드 예시에서는 amount
필드의 값이 0이 아닌 모든 레코드를 pandas.DataFrame
객체로 로드하는 방법을 보여 줍니다.
df = client.db.data.find_pandas_all({'amount': {'$gt': 0}}, schema=schema)
pyarrow.Table
인스턴스와 동일한 결과 집합을 로드할 수도 있습니다.
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}}, schema=schema)
또는 polars.DataFrame
인스턴스로 사용할 수 있습니다.
df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
또는 NumPy arrays
객체로 사용할 수 있습니다.
ndarrays = client.db.data.find_numpy_all({'amount': {'$gt': 0}}, schema=schema)
NumPy를 사용할 때 반환 값은 키는 필드이고 값은 해당 numpy.ndarray
인스턴스인 딕셔너리입니다.
참고
앞의 모든 예에서 다음 예와 같이 스키마를 생략할 수 있습니다.
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}})
스키마를 생략하면 PyMongoArrow는 첫 번째 배치에 포함된 데이터를 기반으로 스키마를 자동으로 적용하려고 시도합니다.
집계 작업
애그리게이션 작업을 실행하는 것은 찾기 작업을 실행하는 것과 비슷하지만 수행하는 데 일련의 작업이 필요합니다.
다음은 모든 _id
값이 함께 그룹화되고 해당 amount
값이 합산된 새 데이터 프레임을 출력하는 aggregate_pandas_all()
메서드의 간단한 예입니다.
df = client.db.data.aggregate_pandas_all([{'$group': {'_id': None, 'total_amount': { '$sum': '$amount' }}}])
내장된 문서에 대해 애그리게이션 작업을 실행할 수도 있습니다. 다음 예제에서는 중첩된 txn
필드에서 값을 풀고 각 값의 개수를 계산한 다음 결과를 내림차순으로 정렬된 NumPy ndarray
객체 목록으로 반환합니다.
pipeline = [{'$unwind': '$txns'}, {'$group': {'_id': '$txns', 'count': {'$sum': 1}}}, {'$sort': {"count": -1}}] ndarrays = client.db.data.aggregate_numpy_all(pipeline)
팁
집계 파이프라인에 대한 자세한 내용은 MongoDB Server 설명서를 참조하세요.
MongoDB에 쓰기
write()
메서드를 사용하여 MongoDB에 다음 유형의 객체를 쓸 수 있습니다.
화살표
Table
Pandas
DataFrame
NumPy
ndarray
극지
DataFrame
from pymongoarrow.api import write from pymongo import MongoClient coll = MongoClient().db.my_collection write(coll, df) write(coll, arrow_table) write(coll, ndarrays)
참고
NumPy 배열은 dict[str, ndarray]
으로 지정됩니다.
Ignore Empty Values
write()
메서드는 선택적으로 부울 exclude_none
매개변수를 허용합니다. 이 매개 변수를 True
로 설정하다 하면 운전자 는 데이터베이스 에 빈 값을 쓰기 (write) 않습니다. 이 매개 변수를 False
으로 설정하다 하거나 비워 두면 운전자 는 각 빈 필드 에 대해 None
를 씁니다.
다음 예시 의 코드는 화살표 Table
를 MongoDB 에 두 번 씁니다. 'b'
필드 의 값 중 하나가 None
로 설정하다 됩니다.
write()
메서드에 대한 첫 번째 호출은 exclude_none
매개변수를 생략하므로 기본값은 False
입니다. None
를 포함한 Table
의 모든 값이 데이터베이스 에 기록됩니다. write()
메서드에 대한 두 번째 호출은 exclude_none
을 True
로 설정하므로 'b'
필드 의 빈 값은 무시됩니다.
data_a = [1, 2, 3] data_b = [1, None, 3] data = Table.from_pydict( { "a": data_a, "b": data_b, }, ) coll.drop() write(coll, data) col_data = list(coll.find({})) coll.drop() write(coll, data, exclude_none=True) col_data_exclude_none = list(coll.find({})) print(col_data) print(col_data_exclude_none)
{'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2, 'b': None} {'_id': ObjectId('...'), 'a': 3, 'b': 3} {'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2} {'_id': ObjectId('...'), 'a': 3, 'b': 3}
다른 형식으로 쓰기
결과 세트가 로드되면 패키지가 지원하는 모든 형식으로 결과를 작성할 수 있습니다.
예를 들어, 변수 arrow_table
가 참고 테이블을 example.parquet
Parquet 파일에 쓰려면 다음 코드를 실행하세요.
import pyarrow.parquet as pq pq.write_table(arrow_table, 'example.parquet')
Pandas는 또한 DataFrame
인스턴스를 CSV 및 HDF를 포함한 다양한 형식으로 쓸 수 있도록 지원합니다. 변수 df
가 참고하는 데이터 프레임을 out.csv
라는 이름의 CSV 파일에 쓰려면 다음 코드를 실행하세요.
df.to_csv('out.csv', index=False)
폴라 API는 앞의 두 가지 예를 혼합한 것입니다.
import polars as pl df = pl.DataFrame({"foo": [1, 2, 3, 4, 5]}) df.write_parquet('example.parquet')
참고
중첩된 데이터는 Parquet 읽기 및 쓰기 작업에 지원되지만 CSV 읽기 및 쓰기 작업에 대해서는 Arrow 또는 Pandas에서 잘 지원되지 않습니다.