11#!/usr/bin/env python
22
33import warnings
4+ import numpy as np
45from sklearn .decomposition import PCA , FastICA , IncrementalPCA , KernelPCA , FactorAnalysis , TruncatedSVD , SparsePCA , MiniBatchSparsePCA , DictionaryLearning , MiniBatchDictionaryLearning
56from sklearn .manifold import TSNE , MDS , SpectralEmbedding , LocallyLinearEmbedding , Isomap
67from umap import UMAP
@@ -92,7 +93,7 @@ def reduce(x, reduce='IncrementalPCA', ndims=None, normalize=None, align=None,
9293 if reduce is None :
9394 return x
9495
95- elif isinstance (reduce , ( str , np .string_ )):
96+ elif isinstance (reduce , str ): # Remove np.string_ check as it's deprecated in NumPy 2.0
9697 model_name = reduce
9798 model_params = {
9899 'n_components' : ndims
@@ -112,7 +113,7 @@ def reduce(x, reduce='IncrementalPCA', ndims=None, normalize=None, align=None,
112113
113114 try :
114115 # if the model passed is a string, make sure it's one of the supported options
115- if isinstance (model_name , ( str , np .string_ )):
116+ if isinstance (model_name , str ): # Remove np.string_ check as it's deprecated in NumPy 2.0
116117 model = models [model_name ]
117118 # otherwise check any custom object for necessary methods
118119 else :
@@ -142,16 +143,18 @@ def reduce(x, reduce='IncrementalPCA', ndims=None, normalize=None, align=None,
142143 if model_params ['n_components' ] is None or all ([i .shape [1 ] <= model_params ['n_components' ] for i in x ]):
143144 return x
144145
145- stacked_x = np .vstack (x )
146+ # Handle empty arrays and type conversion
147+ stacked_x = np .vstack ([np .asarray (arr , dtype = np .float64 ) for arr in x ])
148+
146149 if stacked_x .shape [0 ] == 1 :
147150 warnings .warn ('Cannot reduce the dimensionality of a single row of'
148151 ' data. Return zeros length of ndims' )
149- return [np .zeros ((1 , model_params ['n_components' ]))]
150-
152+ return [np .zeros ((1 , model_params ['n_components' ]), dtype = np .float64 )]
151153
152154 elif stacked_x .shape [0 ] < model_params ['n_components' ]:
153155 warnings .warn ('The number of rows in your data is less than ndims.'
154156 ' The data will be reduced to the number of rows.' )
157+ model_params ['n_components' ] = stacked_x .shape [0 ]
155158
156159 # deprecation warnings
157160 if normalize is not None :
@@ -179,8 +182,17 @@ def reduce(x, reduce='IncrementalPCA', ndims=None, normalize=None, align=None,
179182
180183# sub functions
181184def reduce_list (x , model ):
185+ """Helper function to reduce a list of arrays"""
186+ # Ensure all arrays are float64 for consistent handling
187+ x = [np .asarray (arr , dtype = np .float64 ) for arr in x ]
182188 split = np .cumsum ([len (xi ) for xi in x ])[:- 1 ]
183- x_r = np .vsplit (model .fit_transform (np .vstack (x )), split )
189+ stacked = np .vstack (x )
190+
191+ # Handle potential NaN values
192+ if np .any (np .isnan (stacked )):
193+ warnings .warn ('NaN values detected in input data. These may affect the reduction results.' )
194+
195+ x_r = np .vsplit (model .fit_transform (stacked ), split )
184196 if len (x ) > 1 :
185197 return [xi for xi in x_r ]
186198 else :
0 commit comments