@@ -4795,12 +4795,13 @@ cdef class FixedShapeTensorArray(ExtensionArray):
47954795
47964796 arrow_type = from_numpy_dtype(obj.dtype)
47974797 shape = np.take(obj.shape, permutation)
4798+ permutation = _invert_permutation(permutation[1 :] - 1 )
47984799 values = np.ravel(obj, order = " K" )
47994800
48004801 return ExtensionArray.from_storage(
48014802 fixed_shape_tensor(arrow_type, shape[1 :],
48024803 dim_names = dim_names,
4803- permutation = permutation[ 1 :] - 1 ),
4804+ permutation = permutation),
48044805 FixedSizeListArray.from_arrays(values, shape[1 :].prod())
48054806 )
48064807
@@ -4998,15 +4999,20 @@ def _infer_uniform_shape(shape_rows, ndim):
49984999 return inferred
49995000
50005001
5002+ def _invert_permutation (permutation ):
5003+ return [int (x) for x in
5004+ np.argsort(np.array(permutation, dtype = np.int64), kind = " stable" )]
5005+
5006+
50015007def _permutation_from_strides (arr ):
5002- """ Infer the dimension permutation from array strides.
5008+ """ Infer the logical-to-physical permutation from array strides.
50035009
50045010 Note: for arrays with size-1 dimensions, the inferred permutation
50055011 may be unreliable since size-1 strides are unconstrained. Callers
50065012 should skip permutation validation for such arrays.
50075013 """
5008- return [ int (x) for x in
5009- (- np.array(arr.strides, dtype = np.int64)).argsort(kind = " stable" )]
5014+ return _invert_permutation(
5015+ (- np.array(arr.strides, dtype = np.int64)).argsort(kind = " stable" ))
50105016
50115017
50125018cdef class VariableShapeTensorArray(ExtensionArray):
@@ -5070,7 +5076,8 @@ cdef class VariableShapeTensorArray(ExtensionArray):
50705076 dim_names : tuple or list of strings, default None
50715077 Explicit names to tensor dimensions.
50725078 permutation : tuple or list of integers, default None
5073- Physical permutation for all input arrays. If None, inferred from strides.
5079+ Logical-to-physical permutation for all input arrays. If None,
5080+ inferred from strides.
50745081 uniform_shape : tuple or list of integers or None, default None
50755082 Optional known uniform dimensions in physical order. If None, inferred.
50765083
@@ -5151,8 +5158,9 @@ cdef class VariableShapeTensorArray(ExtensionArray):
51515158 (f" obj[{i}] has permutation {ndarray_permutation_list}; "
51525159 f" expected {list(normalized_permutation)}" ))
51535160
5161+ physical_to_logical = _invert_permutation(normalized_permutation)
51545162 shape_rows = [
5155- [int (x) for x in np.take(arr.shape, normalized_permutation )]
5163+ [int (x) for x in np.take(arr.shape, physical_to_logical )]
51565164 for arr in arrays
51575165 ]
51585166
@@ -5173,10 +5181,10 @@ cdef class VariableShapeTensorArray(ExtensionArray):
51735181 if arr.size > 0 :
51745182 raveled = np.ravel(arr, order = " K" )
51755183 physical_shape = tuple (
5176- np.take(arr.shape, normalized_permutation ))
5184+ np.take(arr.shape, physical_to_logical ))
51775185 reconstructed = raveled.reshape(physical_shape)
5178- inv_perm = list ( np.argsort(normalized_permutation))
5179- reconstructed_logical = np.transpose(reconstructed, inv_perm )
5186+ reconstructed_logical = np.transpose(reconstructed,
5187+ normalized_permutation )
51805188 if not np.array_equal(reconstructed_logical, arr):
51815189 raise ValueError (
51825190 " Array memory layout is incompatible with variable "
0 commit comments