2

how can be replaced empty attributes with the next available values ?

I tried

NullAttributeMapper

but somehow I dont get desired results!

What I have:

attribute1, , ,attribute4
 ,attribute2,attribute3,attribute4

what I want:

attribute1,attribute4
attribute2,attribute3,attribute4

can somebody help me ?

1

The question could be a tad clearer; however one answer would be to use iteration and fmeobjects within the pythoncaller. In this way all the attribute values are shifted 'leftwards' of the given order.

Enter the following python code in a pythoncaller transformer. The self.attributelist variable is to be configured with the desired ordered list of attribute names.

If an attribute value is empty (i.e. equal to "") then iteration is used to find the next non-empty value and that value is assigned. As we are shifting, the assignor is then reset and the loop started again.

Code for the pythoncaller:

import fme
import fmeobjects
# Template Function interface:
# When using this function, make sure its name is set as the value of
# the 'Class or Function to Process Features' transformer parameter
def processFeature(feature):
    pass

# Template Class Interface:
# When using this class, make sure its name is set as the value of
# the 'Class or Function to Process Features' transformer parameter
class FeatureProcessor(object):
    def __init__(self):

        #setup the desired ordered list of attributes:
        self.attributelist=["attribute1","attribute2","attribute3","attribute4","attribute5","attribute6","attribute7"]

        pass
    def input(self,feature):

        n=len(self.attributelist)
        for i in range (n):   
            if feature.getAttribute(self.attributelist[i]) =="":#check if attribute is empty
                j=i+1
                while j < n:
                    if feature.getAttribute(self.attributelist[j]) !="":#find next attribute which is *not* empty
                        #assign the next value
                        feature.setAttribute(self.attributelist[i],feature.getAttribute(self.attributelist[j]))
                        #as we are shifting, reset assignor
                        feature.setAttribute(self.attributelist[j],"")
                        break
                    j+=1
        self.pyoutput(feature)
    def close(self):
        pass

example input: enter image description here

example output: enter image description here

1

If I understand correctly... if you mean the next feature that has a value, then you can do this with the AttributeManager.

I just tried it on some parks data, and this is my setup:

enter image description here

It means that when a park name is null, then it will be given the name of the nearest park (nearest in record order, not spatially).

There were three steps to set that up:

  1. Expand the Advanced Attribute Value Handling section and set Substitute Missing, Null and Empty to Closest Adjacent Feature

  2. Check the box for Enable Adjacent Feature Attributes and set how many features you want to check. You said the "next" so perhaps you would leave Prior Features to zero and just set Subsequent Features. Here I chose both so I got the nearest, not necessarily the next.

  3. Create a new attribute and set it to the value of the old attribute. Here I created NewAttr and set it to the value of ParkName.

Now you'll get the correct, non-null value in your new attribute.

The alternative was just to set ParkName to the value of ParkName. That would also have worked. So why did I put it in a new attribute? It might not be an issue for you, but I used the Prior Features option. If there was a block of records all null (say features 50-59) then feature 50 gets the value from 49, then feature 51 gets the value from 50, 52 gets it from 51, etc. In other words each null record takes its value from the one that's just been set (because that's now the closest). So feature 59 would take the value of feature 58, which traces back to feature 49, when in reality 59 is closer to 60 than 49. If I make a new attribute, then the original is not affected, and records 50-54 would get the value of 49, and 55-59 would get the value of 60.

OK, that last bit's a bit of a brain-teaser, but if you don't use the Prior Features option, and just look for subsequent features it won't be an issue. I put it just in case you meant "nearest" not "next", and for any other users who happen to have a similar issue and find this answer.

Whether I understood correctly or not, I think finding adjacent values is an interesting problem, so I put together a solution and added it to the FME Hub. You can find it here: https://hub.safe.com/publishers/safe-lab/transformers/adjacentfeaturenullattributemapper

  • Hi Mark, thanks a lot for your countribution but its not exactly what I need :-( As you can see in my example I need that "attribute 4" come 2 places forward in order to fill 2 empty gaps between 1 and 4. Or in the next row the same either first attribute that is missing somehow should be deleted at all or "attribute2", "attribute3" and "attribute4" shift forward in order to fill the gap. Your setup fills all the gaps in square form like matrix 5x5 but as you can see I have in the first row 2 attributes and second row 3and it should stay like that only gaps in between are to be filled – gisgis May 23 at 19:05

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.