이 튜토리얼은 PyMongoArrow 작업을 소개하기 위한 것입니다. 이 튜토리얼에서는 독자가 기본 PyMongo 및 MongoDB 개념에 익숙하다고 가정합니다.
PyMongoArrow 설치
세 가지 방법으로 PyMongoArrow 를 설치할 수 있습니다.
핍
Conda
소스에서
Pip으로 설치
pip를 사용하여 모든 플랫폼에 PyMongoArrow를 설치하는 것이 좋습니다. PyMongoArrow는 PyPI에서 사용할 수 있습니다.
python -m pip install pymongoarrow
특정 버전의 pymongo를 가져오려면 다음을 수행하세요.
python -m pip install pymongoarrow==1.5.1
pip를 사용하여 업그레이드하려면 다음을 수행합니다.
python -m pip install --upgrade pymongoarrow
중요
ValueError: Could
not find "libbson-1.0" library 과 같은 오류로 인해 설치가 실패하면 pip 이(가) 플랫폼에 적합한 바퀴를 찾지 못했음을 의미합니다. 먼저 pip >= 20.3이 설치되어 있는지 확인하는 것이 좋습니다. pip 를 업그레이드하려면 다음 shell 명령을 실행합니다.
$ python -m pip install --upgrade pip
그런 다음 pymongoarrow 을(를) 다시 설치할 수 있습니다.
현재 x86_64 아키텍처에서 macOS, Windows, Linux에 대한 바퀴를 배포하고 있습니다.
설치를 테스트하려면 Python 셸 에서 다음 코드를 실행 . PyMongoArrow가 올바르게 설치되었다면 오류나 예외가 표시되지 않습니다.
import pymongoarrow as pma
Conda로 설치
conda 사용자는 다음 shell 명령을 실행하여 PyMongoArrow를 사용할 수 있습니다.
$ conda install --channel conda-forge pymongoarrow
설치를 테스트하려면 Python 셸 에서 다음 코드를 실행 . PyMongoArrow가 올바르게 설치되었다면 오류나 예외가 표시되지 않습니다.
import pymongoarrow as pma
소스에서 설치
위 옵션을 사용하여 시스템에 pymongoarrow 를 설치할 수 없는 경우 소스에서 설치할 수 있습니다. 방법을 학습 기여 가이드를 참조하세요.
Dependencies
Linux 의 소스에서 설치하려면 다음과 같은 종속성이 필요합니다.
GCC 버전 12 이상
C 메이크
pkg-config
선택적 종속성이 필요한 PyMongo 기능 과 함께 PyMongoArrow를 사용하려면 PyMongo 를 설치할 때 종속성을 옵션으로 설정하다 해야 합니다.
참고
PyMongo의 선택적 종속성에 대해 자세히 학습하려면 PyMongo 문서에서 종속성 을 참조하세요.
예를 들어, 클라이언트 측 필드 레벨 암호화와 함께 PyMongoArrow를 사용하려면 PyMongoArrow 설치와 함께 encryption 옵션을 사용하여 PyMongo를 설치해야 합니다.
python -m pip install 'pymongo[encryption]' pymongoarrow
쿼리 결과 세트를 pandas.DataFrame 인스턴스로 반환하는 PyMongoArrow API를 사용하는 애플리케이션(예: ~pymongoarrow.api.find_pandas_all())에도 pandas 가 설치되어 있어야 합니다.
python -m pip install pandas
설치를 테스트하려면 Python 셸 에서 다음 코드를 실행 . PyMongoArrow가 올바르게 설치되었다면 오류나 예외가 표시되지 않습니다.
import pymongoarrow as pma
MongoDB 설치
이 튜토리얼에서는 MongoDB 인스턴스 기본값 호스팅하다 및 포트에서 실행 가정합니다. MongoDB 다운로드하여 설치한 후에는 다음 코드 예시 와 같이 시작할 수 있습니다.
$ mongod
샘플 데이터 삽입
다음 코드를 실행하여 클러스터 에 샘플 데이터를 삽입합니다.
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에 다음 유형의 객체를 쓸 수 있습니다.
화살표
TablePandas
DataFrameNumPy
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에서 잘 지원되지 않습니다.
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 메서드를 호출할 때 작업을 실행할 인스턴스를 첫 번째 인수로 전달해야 합니다.
문제 해결
undefined symbol 소스에서 PyMongoArrow를 설치할 때 오류가 발생하는 이유는 무엇인가요?
Linux 환경에 GCC 버전 12 이상이 설치되지 않은 경우 PyMongoArrow가 이 오류를 발생시킵니다. 이 오류가 발생하면 GCC 버전 12 이상이 설치되어 있는지 확인하세요.
ModuleNotFoundError: No module named 'polars' PyMongoArrow를 사용할 때 가 표시되는 이유는 무엇인가요?
PyMongoArrow는 애플리케이션이 Python 환경에 polars 을(를) 설치하지 않고도 쿼리 결과 세트를 polars.DataFrame 인스턴스로 반환하는 PyMongoArrow API를 사용하려고 할 때 이 오류를 발생시킵니다. polars 은(는) PyMongoArrow 의 직접적인 종속 항목이 아니므로, pymongoarrow 를 설치할 때 자동으로 설치되지 않습니다. 다음 shell 명령을 사용하여 polars 를 별도로 설치해야 합니다.
python -m pip install polars