Dzielenie tekstu z pola ciągu przed każdym separatorem na nowe pola


9

Próbuję wyodrębnić dane tekstowe z pola tekstowego zawierającego tekst rozdzielony kropkami i umieścić go w nowych polach za pomocą kalkulatora pól.

Używam tej funkcji Pythona (zaczerpnięte z Jak wyodrębnić tekst przed / w QGIS? ):

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

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

Zwraca cały tekst przed pierwszą kropką. Teraz zastanawiam się, jak napisać funkcję, aby umieściła każdy rozdzielany wiersz tekstu w osobnym polu.

Przed:

Stoły

Po:

Stoły

Odpowiedzi:


10

EDYCJA : Zredagowałem odpowiedź zgodnie z niektórymi komentarzami JWesa .


Możesz uruchomić prosty skrypt z konsoli Python . Najpierw otwórz konsolę Python z Plugins> Python Consolei aktywuj przycisk Editor:

wprowadź opis zdjęcia tutaj

Następnie załaduj obiekt (wektor, tabelę itp.), W którym przechowywane są dane.

Po wykonaniu tej czynności skopiuj następujący kod do 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()

a następnie uruchom:

wprowadź opis zdjęcia tutaj

Otrzymasz to:

wprowadź opis zdjęcia tutaj

Jeśli wolisz, możesz oczywiście użyć powyższego kodu jako funkcji Pythona dla kalkulatora pola (widziałem, że już wiesz, jak to zrobić).


Pojawia się komunikat o błędzie: plik wykonywalny (u'c: /users/jonwes~1/appdata/local/temp/tmpt2lphm.py'.encode ('mbcs')) Traceback (ostatnie połączenie ostatnio): Plik "<wejście> ", wiersz 1, w <module> Plik" c: /users/jonwes~1/appdata/local/temp/tmpt2lphm.py ", wiersz 6, w <module> feat [" Atg2 "] = pola [2] IndexError : indeks listy poza zakresem
JWes,

1
Dzieje się tak, ponieważ prawdopodobnie masz pewne ciągi, które różnią się od podanej próbki. Błąd oznacza, że ​​na pozycji nr 2 listy nie ma żadnej wartości fields. Czy mam rację?
mgri

Tak, masz rację, w zasadzie niektóre funkcje mają więcej informacji ograniczonych większą liczbą kropek niż inne funkcje.
JWes

1
Jeśli możesz podać minimalny przykładowy plik (w którym widzę strukturę danych), powinienem być w stanie dostosować kod do twojej sprawy. W przeciwnym razie konieczne będzie wznowienie samodzielnego korzystania z warunków warunkowych, ponieważ istnieje zbyt wiele możliwości zarządzania bez wytycznych.
mgri

W takim razie zaktualizuję oryginalne pytanie bardziej szczegółowo na temat struktury danych!
JWes

6

Nie jest to bardzo skuteczna metoda, ale wcześniej jej użyłem. Upewnij się Field2i Field3istnieje, a następnie użyj czegoś takiego:

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

Przykład :

  1. Oto atrybut:

    Tabela atrybutów

  2. Następnie po zapisaniu skryptu wybierz opcję aktualizacji Field1i użyj wyrażenia:

    func("Field1")

    Edytor funkcji

  3. Wynik:

    Wynik


1
Mieliśmy ten sam pomysł! =)
mgri

1
@HowToInQGIS - Rzeczywiście, chociaż zdecydowanie wolę twoją metodę, ponieważ jest o wiele łatwiejsza :)
Joseph
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.