code: def _features_from_attributes(node_type, ids, values, dtype):
      # the size is the first element that has a length, or None if there's only None elements.
      size = next((len(x) for x in values if x is not None), None)
  
      num_nodes = len(ids)
  
      if size is None:
          # no features = zero-dimensional features, and skip the loop below
          return zero_sized_array((num_nodes, 0), dtype)
  
      default_value = np.zeros(size, dtype)
  
      missing = []
  
      def compute_value(node_id, x):
          if x is None:
              missing.append(node_id)
              return default_value
          elif len(x) != size:
              raise ValueError(
                  f"inferred all nodes of type {node_type!r} to have feature dimension {size}, found dimension {len(x)}"
              )
  
          return x
  
      matrix = np.array(
          [
              compute_value(node_id, x)
              for node_id, x in zip(ids, values)
          ],
          dtype,
      )
      assert matrix.shape == (num_nodes, size)
  
      if missing:
          # user code is 5 frames above the warnings.warn call
          stacklevel = 5
          warnings.warn(
              f"found the following nodes (of type {node_type!r}) without features, using {size}-dimensional zero vector: {comma_sep(missing)}",
              stacklevel=stacklevel,
          )
  
      return matrix
  
imports: from collections import defaultdict, namedtuple
  from typing import Iterable
  import warnings
  import numpy
  import pandas
  from ..globalvar import SOURCE, TARGET, WEIGHT, TYPE_ATTR_NAME
  from .element_data import NodeData, EdgeData
  from .indexed_array import IndexedArray
  from .validation import comma_sep, require_dataframe_has_columns
  from .utils import is_real_iterable, zero_sized_array, smart_array_concatenate, smart_array_index
label_desc: Use image node_id 4 for calling a global function with example usage: _features_from_attributes(node_type, ids, values, dtype) and returns: matrix, zero_sized_array, x, default_value