고정 너비 파일을 효율적으로 구문 분석
고정 너비 파일은 미리 결정된 열 길이로 인해 고유한 구문 분석 문제를 나타냅니다. 이러한 파일에서 데이터를 추출하는 효율적인 방법을 찾는 것은 데이터 처리에 매우 중요합니다.
문제 설명
각 열이 특정 값을 나타내는 고정 너비 선이 있는 파일이 제공됩니다. , 이러한 행을 별도의 구성 요소로 구문 분석하는 효율적인 방법을 개발하십시오. 현재 스트링 슬라이싱을 채택하고 있으나 대용량 파일에 대한 가독성 및 적합성에 대한 우려가 있습니다.
해결책
두 가지 효율적인 구문 분석 방법을 제시합니다.
방법 1: 구조체 사용 모듈
Python 표준 라이브러리의 struct 모듈은 바이너리 데이터 스트림에서 데이터를 압축 해제하는 편리한 방법을 제공합니다. 각 필드의 너비와 유형을 지정하는 형식 문자열을 정의하여 고정 너비 파일과 함께 사용할 수 있습니다. 이 방법은 속도와 단순성을 모두 제공합니다.
예:
<code class="python">import struct fieldwidths = (2, -10, 24) fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's') for fw in fieldwidths) # Convert Unicode input to bytes and the result back to Unicode string. unpack = struct.Struct(fmtstring).unpack_from # Alias. parse = lambda line: tuple(s.decode() for s in unpack(line.encode())) print('fmtstring: {!r}, record size: {} chars'.format(fmtstring, struct.calcsize(fmtstring))) line = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n' fields = parse(line) print('fields: {}'.format(fields))</code>
방법 2: 컴파일에 문자열 슬라이싱 사용
문자열 분할이 간단해 보일 수 있지만 다음을 사용하여 보다 효율적인 버전을 컴파일하면 속도를 향상시킬 수 있습니다. 평가(). 이 방법은 상수이므로 실행 속도가 더 빠른 슬라이스 경계 목록을 생성합니다.
예(최적화):
<code class="python">def make_parser(fieldwidths): cuts = tuple(cut for cut in accumulate(abs(fw) for fw in fieldwidths)) pads = tuple(fw < 0 for fw in fieldwidths) # bool flags for padding fields flds = tuple(zip_longest(pads, (0,)+cuts, cuts))[:-1] # ignore final one slcs = ', '.join('line[{}:{}]'.format(i, j) for pad, i, j in flds if not pad) parse = eval('lambda line: ({})\n'.format(slcs)) # Create and compile source code. # Optional informational function attributes. parse.size = sum(abs(fw) for fw in fieldwidths) parse.fmtstring = ' '.join('{}{}'.format(abs(fw), 'x' if fw < 0 else 's') for fw in fieldwidths) return parse</code>
두 방법 모두 효율적인 구문 분석 방법을 제공합니다. 고정 너비 파일. struct 모듈을 사용하는 방법 1은 사용하기 쉬운 반면, 최적화된 문자열 분할을 사용하는 방법 2는 최적화 시 약간 더 나은 성능을 제공합니다.
위 내용은 Python에서 고정 너비 파일을 효율적으로 구문 분석하는 방법: 구조체 모듈과 최적화된 문자열 슬라이싱?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!