class_docstr: A plain python object modeling a heterogeneous graph with various
  attributes (Node types in :class:`HeteroGraph` require string type).
  
  Args:
      G (:class:`networkx.classes.graph`): A NetworkX graph object which
          contains features and labels for each node type and edge type.
      **kwargs: Keyworded argument list with keys such
          as :obj:`"node_feature"`, :obj:`"node_label"` and
          corresponding attributes.
class_docstr_tok: ["A","plain","python","object","modeling","a","heterogeneous","graph","with","various","attributes","(","Node","types","in",":","class",":","`","HeteroGraph","`","require","string","type",")",".","Args",":","G","(",":","class",":","`","networkx.classes.graph","`",")",":","A","NetworkX","graph","object","which","contains","features","and","labels","for","each","node","type","and","edge","type",".","*","*","kwargs",":","Keyworded","argument","list","with","keys","such","as",":","obj",":","`","``","node_feature","''","`",",",":","obj",":","`","``","node_label","''","`","and","corresponding","attributes","."]
docstr: Returns the node attributes in the graph. Multiple attributes will
  be stacked.
  
  Args:
      key(string): the name of the attributes to return.
  
  Returns:
      a dictionary of node type to torch.tensor: node attributes.
docstr_tok: ["Returns","the","node","attributes","in","the","graph",".","Multiple","attributes","will","be","stacked",".","Args",":","key","(","string",")",":","the","name","of","the","attributes","to","return",".","Returns",":","a","dictionary","of","node","type","to","torch.tensor",":","node","attributes","."]
code: def _get_node_attributes(self, key: str):
      r"""
      Returns the node attributes in the graph. Multiple attributes will
      be stacked.
  
      Args:
          key(string): the name of the attributes to return.
  
      Returns:
          a dictionary of node type to torch.tensor: node attributes.
      """
      attributes = {}
      indices = None
      if key == "node_type":
          indices = {}
  
      for node_idx, (_, node_dict) in enumerate(
          self.G.nodes(data=True)
      ):
          if key in node_dict:
              node_type = self._get_node_type(node_dict)
              if node_type not in attributes:
                  attributes[node_type] = []
              attributes[node_type].append(node_dict[key])
              if indices is not None:
                  if node_type not in indices:
                      indices[node_type] = []
                  # use range(0 ~ num_nodes) as the graph node indices
                  indices[node_type].append(node_idx)
  
      if len(attributes) == 0:
          return None
  
      for node_type, val in attributes.items():
          if torch.is_tensor(attributes[node_type][0]):
              attributes[node_type] = torch.stack(val, dim=0)
          elif isinstance(attributes[node_type][0], float):
              attributes[node_type] = torch.tensor(
                  val, dtype=torch.float
              )
          elif isinstance(attributes[node_type][0], int):
              attributes[node_type] = torch.tensor(
                  val, dtype=torch.long
              )
  
      if indices is not None:
          node_to_tensor_mapping = torch.zeros(
              [
                  self.G.number_of_nodes(),
              ],
              dtype=torch.int64,
          )
          for node_type in indices:
              # row 0 for graph index, row 1 for tensor index
              indices[node_type] = torch.tensor(
                  indices[node_type], dtype=torch.int64
              )
              node_to_tensor_mapping[indices[node_type]] = torch.arange(
                  len(indices[node_type]), dtype=torch.int64
              )
          self.node_to_graph_mapping = indices
          self.node_to_tensor_mapping = node_to_tensor_mapping
  
      return attributes
  
imports: import math
  import copy
  import random
  import torch
  import networkx
  import numpy
  from deepsnap.graph import Graph
  from typing import Dict, List, Union
  import warnings
label_desc: Use image node_id 15 for calling the HeteroGraph obj's underlying member method code with example usage: obj._get_node_attributes(key) and returns: attributes, None