소개
이 랩에서는 Python 제너레이터를 활용하여 효율적인 데이터 처리 파이프라인을 구축하는 방법을 배우게 됩니다. 제너레이터는 Python 의 강력한 기능으로, 모든 데이터를 동시에 메모리에 저장할 필요 없이 필요에 따라 데이터를 생성할 수 있게 해줍니다. Unix 파이프와 유사한 데이터 처리 워크플로우를 만들기 위해 제너레이터를 연결하는 방법을 배우게 될 것입니다.
이 랩의 목표는 제너레이터 기반 처리 파이프라인의 기본 사항을 이해하고, Python 제너레이터를 사용하여 데이터 처리 워크플로우를 생성하며, 실시간 데이터 스트림을 필터링하고 형식화하는 것입니다. ticker.py 파일은 이 랩에서 생성될 것입니다. 이 연습을 위해 stocksim.py 프로그램이 백그라운드에서 실행 중이어야 하며, 이전 연습에서 사용했던 follow() 함수를 사용하게 됩니다.
CSV 데이터를 사용한 기본 제너레이터 파이프라인
이 단계에서는 제너레이터를 사용하여 기본 처리 파이프라인을 만드는 방법을 배우겠습니다. 하지만 먼저 제너레이터가 무엇인지 이해해 봅시다. 제너레이터는 Python 에서 특별한 유형의 이터레이터입니다. 모든 데이터를 한 번에 메모리에 로드할 수 있는 일반 이터레이터와 달리, 제너레이터는 필요에 따라 값을 생성합니다. 이는 대량의 데이터 스트림을 처리할 때 메모리를 절약하므로 매우 유용합니다. 전체 데이터 세트를 메모리에 저장하는 대신, 제너레이터는 필요에 따라 값을 하나씩 생성합니다.
제너레이터 이해
제너레이터는 본질적으로 이터레이터를 반환하는 함수입니다. 이 이터레이터를 반복하면 일련의 값이 생성됩니다. 제너레이터 함수를 작성하는 방법은 일반 함수와 유사하지만 중요한 차이점이 있습니다. return 문 대신 제너레이터 함수는 yield 문을 사용합니다. yield 문은 고유한 동작을 합니다. 함수를 일시 중지하고 현재 상태를 저장합니다. 다음 값을 요청하면 함수는 중단된 지점부터 계속됩니다. 이를 통해 제너레이터는 매번 처음부터 시작하지 않고도 값을 점진적으로 생성할 수 있습니다.
follow() 함수 사용
이전에 생성한 follow() 함수는 Unix 의 tail -f 명령과 유사하게 작동합니다. tail -f 명령은 파일의 새 콘텐츠를 지속적으로 모니터링하며, follow() 함수도 마찬가지입니다. 이제 이를 사용하여 간단한 처리 파이프라인을 만들어 보겠습니다.
1 단계: 새 터미널 창 열기
먼저 WebIDE 에서 새 터미널 창을 엽니다. Terminal → New Terminal로 이동하여 이 작업을 수행할 수 있습니다. 이 새 터미널은 Python 명령을 실행할 곳입니다.
2 단계: Python 대화형 셸 시작
새 터미널이 열리면 Python 대화형 셸을 시작합니다. 터미널에 다음 명령을 입력하여 이 작업을 수행할 수 있습니다.
python3
Python 대화형 셸을 사용하면 Python 코드를 한 줄씩 실행하고 결과를 즉시 확인할 수 있습니다.
3 단계: follow 함수를 가져오고 파이프라인 설정
이제 follow 함수를 가져와 주식 데이터를 읽기 위한 기본 파이프라인을 설정합니다. Python 대화형 셸에서 다음 코드를 입력합니다.
>>> from follow import follow
>>> import csv
>>> lines = follow('stocklog.csv')
>>> rows = csv.reader(lines)
>>> for row in rows:
... print(row)
...
각 줄의 기능은 다음과 같습니다.
from follow import follow:follow모듈에서follow함수를 가져옵니다.import csv: Python 에서 CSV 파일을 읽고 쓰기 위해 사용되는csv모듈을 가져옵니다.lines = follow('stocklog.csv'): 파일 이름stocklog.csv로follow함수를 호출합니다.follow함수는 파일에 새 줄이 추가될 때마다 생성되는 제너레이터를 반환합니다.rows = csv.reader(lines):csv.reader()함수는follow함수에서 생성된 줄을 가져와 CSV 데이터의 행으로 구문 분석합니다.for루프는 이러한 행을 반복하고 각 행을 인쇄합니다.
4 단계: 출력 확인
코드를 실행한 후 다음과 유사한 출력을 볼 수 있습니다 (데이터는 다를 수 있음).
['BA', '98.35', '6/11/2007', '09:41.07', '0.16', '98.25', '98.35', '98.31', '158148']
['AA', '39.63', '6/11/2007', '09:41.07', '-0.03', '39.67', '39.63', '39.31', '270224']
['XOM', '82.45', '6/11/2007', '09:41.07', '-0.23', '82.68', '82.64', '82.41', '748062']
['PG', '62.95', '6/11/2007', '09:41.08', '-0.12', '62.80', '62.97', '62.61', '454327']
...
이 출력은 데이터 파이프라인을 성공적으로 생성했음을 나타냅니다. follow() 함수는 파일에서 줄을 생성하고, 이러한 줄은 csv.reader() 함수로 전달되어 데이터 행으로 구문 분석됩니다.
출력이 충분히 표시되면 Ctrl+C를 눌러 실행을 중지할 수 있습니다.
무슨 일이 일어나고 있나요?
이 파이프라인에서 무슨 일이 일어나고 있는지 자세히 살펴보겠습니다.
follow('stocklog.csv')는 제너레이터를 생성합니다. 이 제너레이터는stocklog.csv파일을 추적하고 파일에 새 줄이 추가될 때마다 생성합니다.csv.reader(lines)는follow함수에서 생성된 줄을 가져와 CSV 행 데이터로 구문 분석합니다. CSV 파일의 구조를 이해하고 줄을 개별 값으로 분할합니다.- 그런 다음
for루프는 이러한 행을 반복하여 각 행을 인쇄합니다. 이를 통해 데이터를 읽을 수 있는 형식으로 볼 수 있습니다.
이것은 제너레이터를 사용한 데이터 처리 파이프라인의 간단한 예입니다. 다음 단계에서는 더 복잡하고 유용한 파이프라인을 구축할 것입니다.
Ticker 클래스 생성
데이터 처리에서 원시 데이터를 사용하는 것은 매우 어려울 수 있습니다. 주식 데이터를 보다 체계적이고 효율적으로 처리하기 위해 주식 시세를 나타내는 적절한 클래스를 정의할 것입니다. 이 클래스는 주식 데이터의 청사진 역할을 하여 데이터 처리 파이프라인을 더욱 강력하고 관리하기 쉽게 만듭니다.
ticker.py 파일 생성
먼저 WebIDE 에서 새 파일을 만들어야 합니다. "New File" 아이콘을 클릭하거나 파일 탐색기에서 마우스 오른쪽 버튼을 클릭하고 "New File"을 선택하여 이 작업을 수행할 수 있습니다. 이 파일의 이름을
ticker.py로 지정합니다. 이 파일은Ticker클래스에 대한 코드를 저장합니다.이제 새로 생성된
ticker.py파일에 다음 코드를 추가해 보겠습니다. 이 코드는Ticker클래스를 정의하고 이를 테스트하기 위한 간단한 처리 파이프라인을 설정합니다.
## ticker.py
from structure import Structure, String, Float, Integer
class Ticker(Structure):
name = String()
price = Float()
date = String()
time = String()
change = Float()
open = Float()
high = Float()
low = Float()
volume = Integer()
if __name__ == '__main__':
from follow import follow
import csv
lines = follow('stocklog.csv')
rows = csv.reader(lines)
records = (Ticker.from_row(row) for row in rows)
for record in records:
print(record)
- 코드를 추가한 후 파일을 저장합니다.
Ctrl+S를 누르거나 메뉴에서 "File" → "Save"를 선택하여 이 작업을 수행할 수 있습니다. 파일을 저장하면 변경 사항이 유지되고 나중에 실행할 수 있습니다.
코드 이해
이 코드가 단계별로 수행하는 작업을 자세히 살펴보겠습니다.
코드 시작 부분에서
structure.py모듈에서Structure및 필드 유형을 가져옵니다. 이 모듈은 이미 설정되어 있습니다. 이러한 가져오기는Ticker클래스의 구성 요소를 제공하므로 필수적입니다.Structure클래스는Ticker클래스의 기본 클래스가 되고,String,Float,Integer와 같은 필드 유형은 주식 데이터 필드의 데이터 유형을 정의합니다.다음으로,
Structure에서 상속되는Ticker클래스를 정의합니다. 이 클래스에는 주식 데이터의 다양한 측면을 나타내는 여러 필드가 있습니다.name: 이 필드는 "IBM" 또는 "AAPL"과 같은 주식 기호를 저장합니다. 이를 통해 어떤 회사의 주식인지 식별할 수 있습니다.price: 주식의 현재 가격을 저장합니다. 이는 투자자에게 중요한 정보입니다.date및time: 이 필드는 주식 시세가 생성된 시점을 알려줍니다. 시간과 날짜를 아는 것은 시간이 지남에 따른 주가 추세를 분석하는 데 중요합니다.change: 이는 주식의 가격 변동을 나타냅니다. 이전 시점과 비교하여 주가가 상승했는지 하락했는지 보여줍니다.open,high,low: 이 필드는 특정 기간 동안 주식의 시초가, 최고가 및 최저가를 나타냅니다. 이를 통해 주식의 가격 범위를 알 수 있습니다.volume: 이 필드는 거래된 주식 수를 저장합니다. 높은 거래량은 특정 주식에 대한 시장의 강한 관심을 나타낼 수 있습니다.
if __name__ == '__main__':블록에서 처리 파이프라인을 설정합니다. 이 코드 블록은ticker.py파일을 직접 실행할 때 실행됩니다.follow('stocklog.csv')는stocklog.csv파일에서 줄을 생성하는 함수입니다. 이를 통해 파일을 한 줄씩 읽을 수 있습니다.csv.reader(lines)는 이러한 줄을 가져와 행 데이터로 구문 분석합니다. CSV(쉼표로 구분된 값) 는 표 형식 데이터를 저장하는 일반적인 파일 형식이며, 이 함수는 각 행에서 데이터를 추출하는 데 도움이 됩니다.(Ticker.from_row(row) for row in rows)는 제너레이터 표현식입니다. 각 데이터 행을 가져와Ticker객체로 변환합니다. 이러한 방식으로 원시 CSV 데이터를 작업하기 쉬운 구조화된 객체로 변환합니다.for루프는 이러한Ticker객체를 반복하고 각 객체를 인쇄합니다. 이를 통해 구조화된 데이터를 실제로 확인할 수 있습니다.
코드 실행
코드를 실행하여 작동 방식을 살펴보겠습니다.
먼저 터미널에서 프로젝트 디렉토리에 있는지 확인해야 합니다. 아직 해당 디렉토리에 있지 않은 경우 다음 명령을 사용하여 이동합니다.
cd /home/labex/project올바른 디렉토리에 있으면 다음 명령을 사용하여
ticker.py스크립트를 실행합니다.python3 ticker.py스크립트를 실행한 후 다음과 유사한 출력을 볼 수 있습니다 (데이터는 다를 수 있음).
Ticker(IBM, 103.53, 6/11/2007, 09:53.59, 0.46, 102.87, 103.53, 102.77, 541633) Ticker(MSFT, 30.21, 6/11/2007, 09:54.01, 0.16, 30.05, 30.21, 29.95, 7562516) Ticker(AA, 40.01, 6/11/2007, 09:54.01, 0.35, 39.67, 40.15, 39.31, 576619) Ticker(T, 40.1, 6/11/2007, 09:54.08, -0.16, 40.2, 40.19, 39.87, 1312959)
출력이 충분히 표시되면 Ctrl+C를 눌러 스크립트 실행을 중지할 수 있습니다.
원시 CSV 데이터가 구조화된 Ticker 객체로 변환된 방식을 확인하십시오. 이 변환을 통해 Ticker 클래스에 정의된 필드를 사용하여 주식 데이터에 액세스하고 조작할 수 있으므로 처리 파이프라인에서 데이터를 훨씬 쉽게 사용할 수 있습니다.
보다 복잡한 데이터 파이프라인 구축
이제 데이터 파이프라인을 다음 단계로 끌어올려 필터링을 추가하고 데이터 표현을 개선할 것입니다. 이렇게 하면 작업 중인 정보를 분석하고 이해하기가 더 쉬워집니다. ticker.py 스크립트를 변경할 것입니다. 데이터를 필터링하면 관심 있는 특정 정보에 집중하는 데 도움이 되며, 이를 잘 형식화된 표로 표시하면 가독성이 향상됩니다.
ticker.py 파일 업데이트
먼저 WebIDE 에서
ticker.py파일을 엽니다. WebIDE 는 브라우저에서 직접 코드를 작성하고 편집할 수 있는 도구입니다. Python 스크립트를 변경하기 위한 편리한 환경을 제공합니다.다음으로,
ticker.py파일의if __name__ == '__main__':블록을 다음 코드로 바꿔야 합니다. 이 코드 블록은 스크립트의 진입점이며, 이를 대체하여 스크립트가 데이터를 처리하고 표시하는 방식을 변경합니다.
if __name__ == '__main__':
from follow import follow
import csv
from tableformat import create_formatter, print_table
formatter = create_formatter('text')
lines = follow('stocklog.csv')
rows = csv.reader(lines)
records = (Ticker.from_row(row) for row in rows)
negative = (rec for rec in records if rec.change < 0)
print_table(negative, ['name', 'price', 'change'], formatter)
- 이러한 변경을 수행한 후 파일을 저장합니다. 키보드에서
Ctrl+S를 누르거나 메뉴에서 "File" → "Save"를 선택하여 이 작업을 수행할 수 있습니다. 파일을 저장하면 변경 사항이 유지되고 나중에 실행할 수 있습니다.
향상된 파이프라인 이해
이 향상된 파이프라인이 수행하는 작업을 자세히 살펴보겠습니다. 각 단계를 이해하면 코드의 서로 다른 부분이 어떻게 함께 작동하여 데이터를 처리하고 표시하는지 알 수 있습니다.
먼저
tableformat모듈에서create_formatter및print_table을 가져오는 것으로 시작합니다. 이 모듈은 이미 설정되어 있으며 데이터를 멋진 표로 형식화하고 인쇄하는 데 도움이 되는 함수를 제공합니다.그런 다음
create_formatter('text')를 사용하여 텍스트 형식 지정자를 만듭니다. 이 형식 지정자는 데이터를 읽기 쉬운 방식으로 형식화하는 데 사용됩니다.이제 파이프라인을 단계별로 분석해 보겠습니다.
follow('stocklog.csv')는stocklog.csv파일에서 줄을 생성하는 함수입니다. 파일에서 새 데이터를 지속적으로 모니터링하고 줄을 하나씩 제공합니다.csv.reader(lines)는follow에서 생성된 줄을 가져와 행 데이터로 구문 분석합니다. CSV 파일의 데이터가 텍스트 형식이고 이를 작업할 수 있는 구조화된 형식으로 변환해야 하므로 필요합니다.(Ticker.from_row(row) for row in rows)는 각 데이터 행을Ticker객체로 변환하는 제너레이터 표현식입니다.Ticker객체는 주식을 나타내며 주식 이름, 가격 및 변동과 같은 정보를 포함합니다.(rec for rec in records if rec.change < 0)는Ticker객체를 필터링하는 또 다른 제너레이터 표현식입니다. 주식의 가격 변동이 음수인 객체만 유지합니다. 이를 통해 가격이 하락한 주식에 집중할 수 있습니다.print_table(negative, ['name', 'price', 'change'], formatter)는 필터링된Ticker객체를 가져와 앞에서 만든 형식 지정자를 사용하여 표로 형식화합니다. 그런 다음 표를 콘솔에 인쇄합니다.
이 파이프라인은 제너레이터의 강력함을 보여줍니다. 파일에서 모든 데이터를 한 번에 메모리에 로드하는 대신 여러 작업 (읽기, 구문 분석, 변환, 필터링) 을 함께 연결하고 데이터를 한 번에 하나씩 처리합니다. 이렇게 하면 메모리를 절약하고 코드를 더 효율적으로 만들 수 있습니다.
향상된 파이프라인 실행
업데이트된 코드를 실행하여 결과를 확인해 보겠습니다.
먼저 터미널에서 프로젝트 디렉토리에 있는지 확인합니다. 아직 해당 디렉토리에 있지 않은 경우 다음 명령을 사용하여 이동할 수 있습니다.
cd /home/labex/project프로젝트 디렉토리에 있으면 다음 명령을 사용하여
ticker.py스크립트를 실행합니다.python3 ticker.py스크립트를 실행한 후 터미널에 잘 형식화된 표가 표시됩니다. 이 표에는 가격 변동이 음수인 주식만 표시됩니다.
name price change ---------- ---------- ---------- C 53.12 -0.21 UTX 70.04 -0.19 AXP 62.86 -0.18 MMM 85.72 -0.22 MCD 51.38 -0.03 WMT 49.85 -0.23 KO 51.6 -0.07 AIG 71.39 -0.14 PG 63.05 -0.02 HD 37.76 -0.19
출력이 충분히 표시되었고 스크립트 실행을 중지하려는 경우 키보드에서 Ctrl+C를 누를 수 있습니다.
제너레이터 파이프라인의 강력함
여기에서 생성한 것은 강력한 데이터 처리 파이프라인입니다. 수행하는 작업을 요약해 보겠습니다.
stocklog.csv파일에서 새 데이터를 지속적으로 모니터링합니다. 즉, 파일에 새 데이터가 추가되면 파이프라인이 자동으로 처리합니다.- 파일에서 CSV 데이터를 구조화된
Ticker객체로 구문 분석합니다. 이렇게 하면 데이터를 더 쉽게 사용하고 작업을 수행할 수 있습니다. - 특정 기준, 이 경우 음수 가격 변동을 기반으로 데이터를 필터링합니다. 이를 통해 가치를 잃고 있는 주식에 집중할 수 있습니다.
- 필터링된 데이터를 읽기 쉬운 표로 형식화하고 표시합니다. 이를 통해 데이터를 쉽게 분석하고 결론을 도출할 수 있습니다.
이 파이프라인에서 제너레이터를 사용하는 주요 장점 중 하나는 최소한의 메모리를 사용한다는 것입니다. 제너레이터는 필요에 따라 값을 생성하므로 모든 데이터를 한 번에 메모리에 저장하지 않습니다. 이는 각 구성 요소가 데이터를 처리하고 다음 구성 요소로 전달하는 Unix 파이프와 유사합니다.
제너레이터를 레고 블록으로 생각할 수 있습니다. 다양한 구조를 만들기 위해 레고 블록을 함께 쌓을 수 있는 것처럼 제너레이터를 결합하여 강력한 데이터 처리 워크플로를 만들 수 있습니다. 이 모듈식 접근 방식을 사용하면 간단하고 재사용 가능한 구성 요소에서 복잡한 시스템을 구축할 수 있습니다.
요약
이 랩에서는 Python 제너레이터를 사용하여 효율적인 데이터 처리 파이프라인을 구축하는 방법을 배웠습니다. follow() 함수를 사용하여 파일에서 새 데이터를 모니터링하고, 주식 시세를 나타내는 Ticker 클래스를 만들고, CSV 데이터를 읽고, 구문 분석하고, 필터링한 다음 결과를 형식화하고 표시하는 다단계 처리 파이프라인을 구축하는 등 여러 가지 중요한 작업을 완료했습니다.
제너레이터 기반 접근 방식은 데이터가 필요에 따라 처리되므로 메모리 효율성, 파이프라인 구성 요소의 쉽고 간편한 조합 및 재사용을 가능하게 하는 모듈성, 복잡한 데이터 흐름을 표현하는 단순성을 포함한 여러 가지 이점을 제공합니다. 이러한 개념은 특히 대규모 데이터 세트 또는 스트리밍 데이터의 경우 실제 데이터 처리에서 일반적으로 적용됩니다.