2

I'd like to be able to split the parcel information in an attribute table from one column

parcel_value = 247/34

into two separated columns by using a PyScript

parcel_num = 247

and

parcel_den = 34

I was starting with this but then ran out of knowledge:

layer = iface.activeLayer()
for field in layer.fields():
    if field.name() == 'parcel_value':
        with edit(layer):
            idx = layer.fields().indexFromName(field.name())
            layer.renameAttribute(idx, 'parcel_num')

2 Answers 2

2

You can use the code snippet below. Instead of renaming and updating the "parcel_value" field, I would recommend adding two new integer fields, since after splitting the attribute values, you now have numeric data, and should store it as such.

layer = iface.activeLayer()
layer.dataProvider().addAttributes([QgsField('parcel_num', QVariant.Int), QgsField('parcel_den', QVariant.Int)])
layer.updateFields()
num_idx = layer.fields().lookupField('parcel_num')
den_idx = layer.fields().lookupField('parcel_den')

att_map = {}

for f in layer.getFeatures():
    if f['parcel_value'] != NULL:
        att_split = f['parcel_value'].split('/')
        num = att_split[0]
        den = NULL
        if len(att_split) == 2:
            if att_split[1]:
                den = att_split[1]
        att_map[f.id()] = {num_idx: num, den_idx: den}
    
layer.dataProvider().changeAttributeValues(att_map)

# Uncomment lines below to delete the original field (personally, I would leave it but it's up to you)

#layer.dataProvider().deleteAttributes([layer.fields().lookupField('parcel_value')])
#layer.updateFields()

Result:

enter image description here

3
  • 1
    And if you want to change something later on, or something goes wrong, you still have your original data to work with :)
    – Matt
    Nov 10, 2022 at 6:09
  • @Ben W: i forgot to mention, that in some cases there is no denominator in the parcel_value column. In that case the value of the parcel_value should land in 'parcel_num'. without adressing that problem, the results are NULL. Otherwise it works perfectly.
    – Marek
    Nov 10, 2022 at 17:30
  • @Marek, see my updated answer which will cover the case you describe.
    – Ben W
    Nov 10, 2022 at 23:20
2

If you have already set the column names of parcel_num and parcel_den in the attribute table, you can run the following code which will extract values before and after the forward slash / into separate columns. The code assumes the column types of the parcel_num and parcel_den are integers.

layer = iface.activeLayer()

with edit(layer):
    for feature in layer.getFeatures():
        value = feature['parcel_val'] # update the field name of the parcel_value 
        print(value)
        feature['parcel_num'] = value.split('/')[0]
        feature['parcel_den'] = value.split('/')[1]
        layer.updateFeature(feature)

Before running the code:

enter image description here

After running the code:

enter image description here

Without PyQGIS, you can also achieve the same results using Field Calculator:

  • Check Update Existing Field and select parcel_num

  • Write the following expression

     regexp_replace("parcel_val" ,'(\\d+)/(\\d+)','\\1')
    

Do the same steps for parcel_den

  • Check Update Existing Field and select parcel_den

  • Write the following expression

     regexp_replace("parcel_val" ,'(\\d+)/(\\d+)','\\2')
    

Where parcel_val is the name of the field that holds the parcel values, for example, 247/34.

You will get the same results as before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.