División de texto de un campo de cadena antes de cada delimitador en nuevos campos

9

Estoy tratando de extraer datos de texto de un campo de cadena que contiene texto delimitado por puntos y colocarlo en nuevos campos usando la calculadora de campo.

Estoy usando esta función de Python (Tomado de ¿Cómo extraer texto antes de un / en QGIS? ):

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def func(value1, feature, parent):
    return value1.split('.')[0]

Esto devuelve todo el texto antes del primer punto. Ahora me pregunto cómo escribir la función para colocar cada fila de texto delimitado en un campo separado.

Antes de:

Mesas

Después:

Mesas

JWes
fuente

Respuestas:

10

EDITAR : edité la respuesta de acuerdo con algunos comentarios de JWes .


Puede ejecutar un script simple desde la Consola Python . En primer lugar, abra la Consola Python desde Plugins> Python Consoley active el botón para Editor:

ingrese la descripción de la imagen aquí

Luego, cargue el objeto (un vector, una tabla, etc.) donde se almacenan sus datos.

Una vez que haya hecho esto, copie el siguiente código en Editor:

layer = iface.activeLayer()
fieldindex = layer.fieldNameIndex("Tasks")
layer.startEditing()
for feat in layer.getFeatures():
    if feat[fieldindex]:
        fields = feat[fieldindex].split('.')
        for i in range(1, len(fields)):
            feat[fieldindex + i] = fields[i - 1]
            layer.updateFeature(feat)
    else:
        continue
layer.commitChanges()

y luego ejecutarlo:

ingrese la descripción de la imagen aquí

Obtendrás esto:

ingrese la descripción de la imagen aquí

Si lo prefiere, obviamente puede usar el código anterior como una función de Python para la calculadora de campo (vi que ya sabe cómo hacerlo).

mgri
fuente
Recibo el mensaje de error: execfile (u'c: /users/jonwes~1/appdata/local/temp/tmpt2lphm.py'.encode ('mbcs')) Traceback (última llamada más reciente): Archivo "<input> ", línea 1, en <module> Archivo" c: /users/jonwes~1/appdata/local/temp/tmpt2lphm.py ", línea 6, en <module> feat [" Atg2 "] = fields [2] IndexError : índice de lista fuera de rango
JWes
1
Esto sucede porque probablemente tenga algunas cadenas que son diferentes de la muestra que ha proporcionado. El error significa que no hay un valor almacenado en la posición No.2 de la lista fields. Estoy en lo cierto?
mgri
Sí, tiene razón, básicamente algunas características tienen más información delimitada por más puntos que otras características.
JWes
1
Si puede proporcionar un archivo de muestra mínimo (donde puedo ver cómo se estructuran sus datos), debería poder adaptar el código a su caso. De lo contrario, debería ser necesario recurrir a condicionales por su cuenta porque hay demasiadas posibilidades de administrar sin una directriz.
mgri
¡Actualizaré la pregunta original con más detalles sobre la estructura de datos entonces!
JWes
6

Este no es un método muy eficiente, pero es uno que usé antes. Asegúrese de existir Field2y Field3luego use algo como lo siguiente:

from qgis.core import *
from qgis.gui import *
import re

@qgsfunction(args='auto', group='Custom')
def func(field, feature, parent):
    # Get active layer
    layer = qgis.utils.iface.activeLayer()
    # Get field indices
    idx_2 = layer.fieldNameIndex('Field2')
    idx_3 = layer.fieldNameIndex('Field3')
    # Extract string values
    first_value = [w for w in re.split('\W', field) if w][0]
    second_value = [w for w in re.split('\W', field) if w][1]
    third_value = [w for w in re.split('\W', field) if w][2]    
    # Update values in fields
    layer.changeAttributeValue(feature.id(), idx_2, second_value)
    layer.changeAttributeValue(feature.id(), idx_3, third_value)
    return first_value

Ejemplo :

  1. Aquí hay un atributo:

    Tabla de atributos

  2. Luego, una vez que haya guardado su script, seleccione actualizar Field1y use la expresión:

    func("Field1")

    Editor de funciones

  3. Resultado:

    Resultado

José
fuente
1
Teníamos la misma idea! =)
mgri
1
@HowToInQGIS - De hecho, aunque prefiero mucho tu método, ya que es mucho más fácil :)
Joseph