@@ -598,6 +598,73 @@ def __iter__(self) -> Iterator[KeyType]:
598
598
yield from self .__data
599
599
600
600
601
+ class FNdArray :
602
+ """
603
+ FNdArray is a wrapper of a NumPy array that stores shape and data type
604
+ of the array if they are specified. Only when both shape and data type
605
+ are provided, will FNdArray initialize a placeholder array through
606
+ np.ndarray(shape, dtype=dtype).
607
+ More details about np.ndarray(...):
608
+ https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html
609
+ """
610
+
611
+ def __init__ (
612
+ self , dtype : Optional [str ] = None , shape : Optional [Iterable [int ]] = None
613
+ ):
614
+ super ().__init__ ()
615
+ self ._dtype : Optional [np .dtype ] = (
616
+ np .dtype (dtype ) if dtype is not None else dtype
617
+ )
618
+ self ._shape : Optional [tuple ] = (
619
+ tuple (shape ) if shape is not None else shape
620
+ )
621
+ self ._data : Optional [np .ndarray ] = None
622
+ if dtype and shape :
623
+ self ._data = np .ndarray (shape , dtype = dtype )
624
+
625
+ @property
626
+ def dtype (self ):
627
+ return self ._dtype
628
+
629
+ @property
630
+ def shape (self ):
631
+ return self ._shape
632
+
633
+ @property
634
+ def data (self ):
635
+ return self ._data
636
+
637
+ @data .setter
638
+ def data (self , array : Union [np .ndarray , List ]):
639
+ if isinstance (array , np .ndarray ):
640
+ if self .dtype and not np .issubdtype (array .dtype , self .dtype ):
641
+ raise TypeError (
642
+ f"Expecting type or subtype of { self .dtype } , but got { array .dtype } ."
643
+ )
644
+ if self .shape and self .shape != array .shape :
645
+ raise AttributeError (
646
+ f"Expecting shape { self .shape } , but got { array .shape } ."
647
+ )
648
+ self ._data = array
649
+
650
+ elif isinstance (array , list ):
651
+ array_np = np .array (array , dtype = self .dtype )
652
+ if self .shape and self .shape != array_np .shape :
653
+ raise AttributeError (
654
+ f"Expecting shape { self .shape } , but got { array_np .shape } ."
655
+ )
656
+ self ._data = array_np
657
+
658
+ else :
659
+ raise ValueError (
660
+ f"Can only accept numpy array or python list, but got { type (array )} "
661
+ )
662
+
663
+ # Stored dtype and shape should match to the provided array's.
664
+ self ._dtype = self ._data .dtype
665
+ self ._shape = self ._data .shape
666
+
667
+
601
668
class Pointer (BasePointer ):
602
669
"""
603
670
A pointer that points to an entry in the current pack, this is basically
0 commit comments