nodes: 0, module; 1, function_definition; 2, function_name:get_rank; 3, parameters; 4, block; 5, identifier:self; 6, identifier:entity; 7, identifier:criteria; 8, default_parameter; 9, expression_statement; 10, comment:# If entity is for instance 'person.household', we get the reference entity 'household' behind the projector; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, comment:# Matrix: the value in line i and column j is the value of criteria for the jth person of the ith entity; 17, expression_statement; 18, comment:# We double-argsort all lines of the matrix.; 19, comment:# Double-argsorting gets the rank of each value once sorted; 20, comment:# For instance, if x = [3,1,6,4,0], y = np.argsort(x) is [4, 1, 0, 3, 2] (because the value with index 4 is the smallest one, the value with index 1 the second smallest, etc.) and z = np.argsort(y) is [2, 1, 4, 3, 0], the rank of each value.; 21, expression_statement; 22, comment:# Build the result vector by taking for each person the value in the right line (corresponding to its household id) and the right column (corresponding to its position); 23, expression_statement; 24, comment:# Return -1 for the persons who don't respect the condition; 25, return_statement; 26, identifier:condition; 27, True; 28, comment:"""
          Get the rank of a person within an entity according to a criteria.
          The person with rank 0 has the minimum value of criteria.
          If condition is specified, then the persons who don't respect it are not taken into account and their rank is -1.
  
          Example:
  
          >>> age = person('age', period)  # e.g [32, 34, 2, 8, 1]
          >>> person.get_rank(household, age)
          >>> [3, 4, 0, 2, 1]
  
          >>> is_child = person.has_role(Household.CHILD)  # [False, False, True, True, True]
          >>> person.get_rank(household, - age, condition = is_child)  # Sort in reverse order so that the eldest child gets the rank 0.
          >>> [-1, -1, 1, 0, 2]
          """; 29, assignment; 30, assignment; 31, assignment; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, call; 38, identifier:entity; 39, conditional_expression:entity if not isinstance(entity, Projector) else entity.reference_entity; 40, identifier:positions; 41, attribute; 42, identifier:biggest_entity_size; 43, binary_operator:np.max(positions) + 1; 44, identifier:filtered_criteria; 45, call; 46, identifier:ids; 47, attribute; 48, identifier:matrix; 49, call; 50, identifier:sorted_matrix; 51, call; 52, identifier:result; 53, subscript; 54, attribute; 55, argument_list; 56, identifier:entity; 57, not_operator; 58, attribute; 59, identifier:entity; 60, identifier:members_position; 61, call; 62, integer:1; 63, attribute; 64, argument_list; 65, identifier:entity; 66, identifier:members_entity_id; 67, attribute; 68, argument_list; 69, attribute; 70, argument_list; 71, identifier:sorted_matrix; 72, identifier:ids; 73, identifier:positions; 74, identifier:np; 75, identifier:where; 76, identifier:condition; 77, identifier:result; 78, unary_operator; 79, call; 80, identifier:entity; 81, identifier:reference_entity; 82, attribute; 83, argument_list; 84, identifier:np; 85, identifier:where; 86, identifier:condition; 87, identifier:criteria; 88, attribute; 89, call; 90, identifier:transpose; 91, identifier:np; 92, identifier:argsort; 93, call; 94, integer:1; 95, identifier:isinstance; 96, argument_list; 97, identifier:np; 98, identifier:max; 99, identifier:positions; 100, identifier:np; 101, identifier:inf; 102, attribute; 103, argument_list; 104, attribute; 105, argument_list; 106, identifier:entity; 107, identifier:Projector; 108, identifier:np; 109, identifier:asarray; 110, list_comprehension; 111, identifier:np; 112, identifier:argsort; 113, identifier:matrix; 114, call; 115, for_in_clause; 116, attribute; 117, argument_list; 118, identifier:k; 119, call; 120, identifier:entity; 121, identifier:value_nth_person; 122, identifier:k; 123, identifier:filtered_criteria; 124, keyword_argument; 125, identifier:range; 126, argument_list; 127, identifier:default; 128, attribute; 129, identifier:biggest_entity_size; 130, identifier:np; 131, identifier:inf
code: def get_rank(self, entity, criteria, condition = True):
          """
          Get the rank of a person within an entity according to a criteria.
          The person with rank 0 has the minimum value of criteria.
          If condition is specified, then the persons who don't respect it are not taken into account and their rank is -1.
  
          Example:
  
          >>> age = person('age', period)  # e.g [32, 34, 2, 8, 1]
          >>> person.get_rank(household, age)
          >>> [3, 4, 0, 2, 1]
  
          >>> is_child = person.has_role(Household.CHILD)  # [False, False, True, True, True]
          >>> person.get_rank(household, - age, condition = is_child)  # Sort in reverse order so that the eldest child gets the rank 0.
          >>> [-1, -1, 1, 0, 2]
          """
  
          # If entity is for instance 'person.household', we get the reference entity 'household' behind the projector
          entity = entity if not isinstance(entity, Projector) else entity.reference_entity
  
          positions = entity.members_position
          biggest_entity_size = np.max(positions) + 1
          filtered_criteria = np.where(condition, criteria, np.inf)
          ids = entity.members_entity_id
  
          # Matrix: the value in line i and column j is the value of criteria for the jth person of the ith entity
          matrix = np.asarray([
              entity.value_nth_person(k, filtered_criteria, default = np.inf)
              for k in range(biggest_entity_size)
              ]).transpose()
  
          # We double-argsort all lines of the matrix.
          # Double-argsorting gets the rank of each value once sorted
          # For instance, if x = [3,1,6,4,0], y = np.argsort(x) is [4, 1, 0, 3, 2] (because the value with index 4 is the smallest one, the value with index 1 the second smallest, etc.) and z = np.argsort(y) is [2, 1, 4, 3, 0], the rank of each value.
          sorted_matrix = np.argsort(np.argsort(matrix))
  
          # Build the result vector by taking for each person the value in the right line (corresponding to its household id) and the right column (corresponding to its position)
          result = sorted_matrix[ids, positions]
  
          # Return -1 for the persons who don't respect the condition
          return np.where(condition, result, -1)