class_docstr: Creates a node-level split with distributional shift based on a given
  node property, as proposed in the `"Evaluating Robustness and Uncertainty
  of Graph Models Under Structural Distributional Shifts"
  <https://arxiv.org/abs/2302.13875>`__ paper
  (functional name: :obj:`node_property_split`).
  
  It splits the nodes in a given graph into five non-intersecting parts
  based on their structural properties.
  This can be used for transductive node prediction tasks with distributional
  shifts.
  It considers the in-distribution (ID) and out-of-distribution (OOD) subsets
  of nodes.
  The ID subset includes training, validation and testing parts, while
  the OOD subset includes validation and testing parts.
  As a result, it creates five associated node mask vectors for each graph,
  three which are for the ID nodes (:obj:`id_train_mask`,
  :obj:`id_val_mask`, :obj:`id_test_mask`), and two which are for the OOD
  nodes (:obj:`ood_val_mask`, :obj:`ood_test_mask`).
  
  This class implements three particular strategies for inducing
  distributional shifts in a graph — based on **popularity**, **locality**
  or **density**.
  
  Args:
      property_name (str): The name of the node property to be used
          (:obj:`"popularity"`, :obj:`"locality"`, :obj:`"density"`).
      ratios ([float]): A list of five ratio values for ID training,
          ID validation, ID test, OOD validation and OOD test parts.
          The values must sum to :obj:`1.0`.
      ascending (bool, optional): Whether to sort nodes in ascending order
          of the node property, so that nodes with greater values of the
          property are considered to be OOD (default: :obj:`True`)
  
  Example:
  .. code-block:: python
  
      from torch_geometric.transforms import NodePropertySplit
      from torch_geometric.datasets.graph_generator import ERGraph
  
      data = ERGraph(num_nodes=1000, edge_prob=0.4)()
  
      property_name = 'popularity'
      ratios = [0.3, 0.1, 0.1, 0.3, 0.2]
      tranaform = NodePropertySplit(property_name, ratios)
  
      data = transform(data)
code: def _compute_popularity_property(
      G: Any, ascending: bool = True
  ) -> Tensor:
      import networkx.algorithms as A
  
      property_values = torch.tensor(list(A.pagerank(G).values()))
      property_values *= -1 if ascending else 1
      return property_values
  
file_path: pytorch_geometric/torch_geometric/transforms/node_property_split.py
imports: from typing import Any, Dict, List
  import torch
  from torch import Tensor
  from torch_geometric.data import Data
  from torch_geometric.data.datapipes import functional_transform
  from torch_geometric.transforms import BaseTransform
  from torch_geometric.utils import to_networkx
label_desc: Use image node_id 3 for calling the NodePropertySplit obj's underlying member method code with example usage: obj._compute_popularity_property(G, ascending) and returns: property_values