1

In QGIS 2.18 there is a shapefile with three fields accordingly

"id" | "Type" | "Value"

I want to get the total sum of all values in the field "Value". How can I achieve that in Python console?

Field "Value" maintains two types of data int() and NULL.

I was trying with a while-loop but it does not work

layer = qgis.utils.iface.activeLayer()

if not layer.isValid():
    raise Exception('Layer is not valid')

features = layer.getFeatures()

for feat in features:
    attr = feat.attributes()[2]

    if attr == NULL:
        continue

    else:
        total = 0
        index = 0
        while index < layer.featureCount():
            total = total + int(attr)
            index = index + 1
return(total)

Moreover, after executing @ahmadhanb's solution I received a correct number but somehow with a strange output type, when print (type(sum(total))) it gives me <type 'NoneType'>. What could be a problem?

How to achieve one number that gives the total sum of a whole field exclusive NULL-values?

References:

  • Try to place the print(total) out of the loop. This will give you one value which is the total value. – ahmadhanb Feb 28 at 13:10
  • It gives one value, but a wrong one... – Taras Feb 28 at 13:13
  • 1
    sum(filter(None,[f['Value'] for f in layer.getFeatures()])) – BERA Feb 28 at 13:15
  • @Taras you can replace print(0) with continue to skip null values. – ahmadhanb Feb 28 at 13:17
  • 1
    Taras - What layer and field type is it and which QGIS version are you using? Would it be possible to share a sample of this data online so that others could test it? The one-liner from @Bera works for me in QGIS 2.18 and 3.4. – Joseph Feb 28 at 15:37
1

In fact your code provides a double number to the actual value. For example, if the total number is 50, your code provides 100. I think the correct code should be something like this:

layer = qgis.utils.iface.activeLayer()

if not layer.isValid():
    raise Exception('Layer is not valid')

features = layer.getFeatures()

total = []
for feat in features:
    attr = feat.attributes()[2]

    if attr == NULL:
        continue

    else:
        total.append((int(attr)))
print(sum(total))

Add a total empty list outside the loop, and if the attr == NULL, it will skip the null values, and if there is a value in the attr it will be appended to the list. Then you can print the sum of the list outside the loop to get one value only.

Here is the screenshot of the output:

enter image description here

  • Looks promising! The problem is that the output of print(type(sum(total))) is <type 'NoneType'>. I need to use it in some further calculations. – Taras Feb 28 at 13:43
  • @Taras But I did not write print(type(sum(total))), I wrote print(sum(total)) which will provide an integer value. The output print(type(sum(total))) is <class 'int'> not <type 'NoneType'> – ahmadhanb Feb 28 at 13:46
  • How can I use this value in my further calculations when the type that I do have is <type 'NoneType'>? – Taras Feb 28 at 13:50
  • That is strange. Why do you get <type 'NoneType'>? I am getting integer output type. – ahmadhanb Feb 28 at 14:06
  • Shouldnt if attr == NULL be if attr is None? – BERA Feb 28 at 14:11

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.