2

I am attempting to delete select columns for the final output of the attribute table that I'm creating.I'm having trouble with deleting the attributes (columns) that I want, regardless of their index position. The major issue is that the code is hard coded based on the field index.

  • I have looked at many answers on this site and other sources. I could not find one that answers this specific question. If there is such an answer please link it and I can remove this question.

  • I'm looking for the versatility in deleting all the attributes except for the ones that I want to show in the attribute table without relying on hard coded indices. I have attempted a variety of conditional statements but could not get it to work.

CODE

# Use a list to collect the index of the fields.
fields = []

# Get the index of each field and add it to list.
for field in huff_model.fields():
    idx = huff_model.fieldNameIndex(field.name())
    fields.append(idx)

# Remove the index of the field from the list for the field that you don't 
# want deleted.
fields.remove(0)
fields.remove(14)
fields.remove(15)

# Delete the fields in the attribute table through their corresponding index 
# in the list.
huff_model.deleteAttributes(fields)

With the current code if you don't already know the position of fields you don't want deleted, than this code doesn't work. Furthermore, if a future layer has a similar attribute table but with even one less or one more field (this assumption is valid given the work I'd doing), hard coding would completely mess up the results as the index of the fields that shouldn't be deleted wouldn't be the same as what is currently coded. Each time the number of fields change, the code would have to be updated which seems completely unnecessary (see above).

My assumption would be to only add the field index to the list if not named field x or field y or field z. However, I cannot get it to work outside of hardcoding the index through fields.remove("insert index of field you don't want deleted") to remove the index of the field from the list of indices that will be used to delete the corresponding fields from the attribute table.

The first image below is my attribute table with the field indices indicated by the arrows which are used in field.remove(). There are 16 fields in total, and I don't want to delete the first, fifteenth and sixteenth fields (0, 14, 15 corresponding indices) from the attribute table.

Table before code is run

enter image description here

The second image below is the same attribute table, but with all the fields deleted except for the first, fifteenth and sixteenth fields from the first image (0, 14, 15 corresponding indices).

Table after code is run

enter image description here

2
  • I'm a bit surprised to be honest. You apparently know how to get an index from a field name (see idx = huff_model.fieldNameIndex(field.name())) but then the question more or less seems to boil down to "how do I get an index from a field name". :) Commented Dec 27, 2017 at 22:59
  • Haha yeah but I can't seem to get a conditional statement to work that only adds the field indices to the list that I want deleted. No conditional I tried allows me to not include x or y or z field in the list of indices. Commented Dec 27, 2017 at 23:05

2 Answers 2

3

This?

field_ids = []
# Fieldnames to keep
fieldnames = set(['CTUID','Primary','Secondary'])
for field in huff_model.fields():
    if field.name() not in fieldnames:
      field_ids.append(huff_model.fieldNameIndex(field.name()))

# Delete the fields in the attribute table through their corresponding index 
# in the list.
huff_model.dataProvider().deleteAttributes(field_ids)
huff_model.updateFields()
6
  • Hi, I'm not sure if that's what I'm looking for. I have no problem updating the fields (see images). I want to change how the current code is hard coded to something more versatile which isn't reliant on the knowledge of the indices of fields in the table and the current number of fields in the table to obtain the result in the second image. Commented Dec 27, 2017 at 23:49
  • I modified my answer, please check it.
    – pnz1337
    Commented Dec 28, 2017 at 1:49
  • It doesn't work, I get a completely blank attribute table using the code. The issue is making sure I only add the fields to the list that I want to delete, and not adding CTUID, Primary, and secondary to that list without hardcoding (see my first comment on why I rather not use hard code if possible). I believe the code you posted currently adds the IDs that I don't want to add to the list. Commented Dec 28, 2017 at 2:22
  • Ohh yes, it's late you need the 'not in'.
    – pnz1337
    Commented Dec 28, 2017 at 2:38
  • Perfect, exactly what I was looking for! Yeah, I should have used not in, doh. Much thanks :D Commented Dec 28, 2017 at 2:52
1

If your data always uses the first and last two columns, something like this may work:

# Determine the total number of fields.
fields = len(huff_model.fields())

# Create a list of indices to remove. 
# Exclude first (0) and last 2 from the list
rmv_list = range(1:(fields - 2))

# Delete the fields in the attribute table through their corresponding index 
# in the list.
huff_model.deleteAttributes(rmv_list)

Also keep in mind that del[-1] will delete the last item in a list.

1
  • Yes this works! I had to do a bit of coding to make it work, but the idea is sound. I would still like a way to reference the names if possible just in case but this solution definitely works much better than what I have currently have :) Commented Dec 28, 2017 at 2:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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