¿Cómo omitir líneas al leer un archivo yaml en python?

Estoy familiarizado con preguntas similares, pero no parecen abordar lo que debería ser un problema simple. Estoy usando Python 2.7x y tratando de leer un archivo YAML que se parece a esto:

%YAML:1.0 radarData: !!opencv-matrix rows: 5 cols: 2 dt: u data: [0, 0, 0, 0, 0, 10, 5, 3, 1, 22] 

Por ahora solo necesito el documento ‘datos:’. Intenté un enfoque de vainilla y luego traté de forzar el salto de las primeras 4 líneas (el segundo fragmento de código que se comenta). Ambos enfoques dieron errores.

 import yaml stream = file('test_0x.yml', 'r') yaml.load(stream) # alternative code snippet # with open('test_0x.yml') as f: # stream = f.readlines()[4:] # yaml.load(stream) 

Cualquier sugerencia sobre cómo saltar las primeras líneas sería muy apreciada.

En realidad, solo necesitas saltarte las primeras 2 líneas.

 import yaml skip_lines = 2 with open('test_0x.yml') as infile: for i in range(skip_lines): _ = infile.readline() data = yaml.load(infile) >>> data {'dt': 'u', 'rows': 5, 'data': [0, 0, 0, 0, 0, 10, 5, 3, 1, 22], 'cols': 2} >>> data['data'] [0, 0, 0, 0, 0, 10, 5, 3, 1, 22] 

Saltarse las primeras 5 líneas también funciona.

Perdí completamente el punto aquí, pero dejo mi respuesta original en la parte inferior como un recordatorio humillante.

La respuesta de mhawke es corta y dulce, y probablemente es preferible. Una solución más complicada: elimine esa directiva mal formada, corrija su etiqueta personalizada y agregue un constructor para ella. Esto tiene la ventaja de corregir esa etiqueta donde sea que aparezca en un archivo, no solo en las primeras líneas.

Mi implementación aquí tiene algunas desventajas: absorbe archivos completos, y no se ha probado en datos complejos, donde el efecto de reemplazar la etiqueta por una adecuada podría tener resultados diferentes a los previstos.

 import yaml def strip_malformed_directive(yaml_file): """ Strip a malformed YAML directive from the top of a file. Returns the slurped (!) file. """ lines = list(yaml_file) first_line = lines[0] if first_line.startswith('%') and ":" in first_line: return "\n".join(lines[1:]) else: return "\n".join(lines) def convert_opencvmatrix_tag(yaml_events): """ Convert an erroneous custom tag, !!opencv-matrix, to the correct !opencv-matrix, in a stream of YAML events. """ for event in yaml_events: if hasattr(event, "tag") and event.tag == u"tag:yaml.org,2002:opencv-matrix": event.tag = u"!opencv-matrix" yield event yaml.add_constructor("!opencv-matrix", lambda loader, node: None) with open("test_0x.yml") as yaml_file: directive_processed = strip_malformed_directive(yaml_file) yaml_events = yaml.parse(directive_processed) matrix_tag_converted = convert_opencvmatrix_tag(yaml_events) fixed_document = yaml.emit(matrix_tag_converted) data = yaml.load(fixed_document) print data 

Respuesta original

yaml.load función yaml.load que está utilizando devuelve un diccionario, al que se puede acceder de la siguiente manera:

 import yaml with open("test_0x.yml") as yaml_file: test_data = yaml.load(yaml_file) print test_data["data"] 

¿Eso ayuda?

Tengo una matriz de cámara generada por aruco_calibration_fromimages.exe , aquí está el archivo yml:

 %YAML:1.0 --- image_width: 4000 image_height: 3000 camera_matrix: !!opencv-matrix rows: 3 cols: 3 dt: d data: [ 3.1943912478853654e+03, 0., 1.9850941722590378e+03, 0., 3.2021356095317910e+03, 1.5509955246019449e+03, 0., 0., 1. ] distortion_coefficients: !!opencv-matrix rows: 1 cols: 5 dt: d data: [ 1.3952810090687282e-01, -3.8313647492178071e-01, 5.0555840762660396e-03, 2.3753464602670597e-03, 3.3952514744179502e-01 ] 

Cargue este yml con este código:

 import cv2 fs = cv2.FileStorage("./calib_asus_chess/cam_calib_asus.yml", cv2.FILE_STORAGE_READ) fn = fs.getNode("camera_matrix") print(fn.mat()) 

Y consigue este resultado:

 [[ 3.19439125e+03 0.00000000e+00 1.98509417e+03] [ 0.00000000e+00 3.20213561e+03 1.55099552e+03] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]