Nump hstack - "ValueError: все входные массивы должны иметь одинаковое количество измерений", но они делают

Я пытаюсь присоединиться к двум массивам numpy. У меня есть набор столбцов/функций после запуска TF-IDF в одном столбце текста. В другом я имею один столбец/функцию, которая является целым числом. Поэтому я читаю в столбце данных поезда и теста, запускаю TF-IDF на этом, а затем я хочу добавить еще один целочисленный столбец, потому что я думаю, что это поможет моему классификатору более точно узнать, как он должен себя вести.

К сожалению, я получаю ошибку в заголовке, когда я пытаюсь запустить hstack, чтобы добавить этот единственный столбец в другой массив numpy.

Вот мой код:

  #reading in test/train data for TF-IDF
  traindata = list(np.array(p.read_csv('FinalCSVFin.csv', delimiter=";"))[:,2])
  testdata = list(np.array(p.read_csv('FinalTestCSVFin.csv', delimiter=";"))[:,2])

  #reading in labels for training
  y = np.array(p.read_csv('FinalCSVFin.csv', delimiter=";"))[:,-2]

  #reading in single integer column to join
  AlexaTrainData = p.read_csv('FinalCSVFin.csv', delimiter=";")[["alexarank"]]
  AlexaTestData = p.read_csv('FinalTestCSVFin.csv', delimiter=";")[["alexarank"]]
  AllAlexaAndGoogleInfo = AlexaTestData.append(AlexaTrainData)

  tfv = TfidfVectorizer(min_df=3,  max_features=None, strip_accents='unicode',  
        analyzer='word',token_pattern=r'\w{1,}',ngram_range=(1, 2), use_idf=1,smooth_idf=1,sublinear_tf=1) #tf-idf object
  rd = lm.LogisticRegression(penalty='l2', dual=True, tol=0.0001, 
                             C=1, fit_intercept=True, intercept_scaling=1.0, 
                             class_weight=None, random_state=None) #Classifier
  X_all = traindata + testdata #adding test and train data to put into tf-idf
  lentrain = len(traindata) #find length of train data
  tfv.fit(X_all) #fit tf-idf on all our text
  X_all = tfv.transform(X_all) #transform it
  X = X_all[:lentrain] #reduce to size of training set
  AllAlexaAndGoogleInfo = AllAlexaAndGoogleInfo[:lentrain] #reduce to size of training set
  X_test = X_all[lentrain:] #reduce to size of training set

  #printing debug info, output below : 
  print "X.shape => " + str(X.shape)
  print "AllAlexaAndGoogleInfo.shape => " + str(AllAlexaAndGoogleInfo.shape)
  print "X_all.shape => " + str(X_all.shape)

  #line we get error on
  X = np.hstack((X, AllAlexaAndGoogleInfo))

Ниже приведен вывод и сообщение об ошибке:

X.shape => (7395, 238377)
AllAlexaAndGoogleInfo.shape => (7395, 1)
X_all.shape => (10566, 238377)



---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-2b310887b5e4> in <module>()
     31 print "X_all.shape => " + str(X_all.shape)
     32 #X = np.column_stack((X, AllAlexaAndGoogleInfo))
---> 33 X = np.hstack((X, AllAlexaAndGoogleInfo))
     34 sc = preprocessing.StandardScaler().fit(X)
     35 X = sc.transform(X)

C:\Users\Simon\Anaconda\lib\site-packages\numpy\core\shape_base.pyc in hstack(tup)
    271     # As a special case, dimension 0 of 1-dimensional arrays is "horizontal"
    272     if arrs[0].ndim == 1:
--> 273         return _nx.concatenate(arrs, 0)
    274     else:
    275         return _nx.concatenate(arrs, 1)

ValueError: all the input arrays must have same number of dimensions

Что вызывает здесь мою проблему? Как я могу это исправить? Насколько я вижу, я могу присоединиться к этим колонкам? Что я неправильно понял?

Спасибо.

Изменить:

Использование метода в ответе ниже получает следующую ошибку:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-16-640ef6dd335d> in <module>()
---> 36 X = np.column_stack((X, AllAlexaAndGoogleInfo))
     37 sc = preprocessing.StandardScaler().fit(X)
     38 X = sc.transform(X)

C:\Users\Simon\Anaconda\lib\site-packages\numpy\lib\shape_base.pyc in column_stack(tup)
    294             arr = array(arr,copy=False,subok=True,ndmin=2).T
    295         arrays.append(arr)
--> 296     return _nx.concatenate(arrays,1)
    297 
    298 def dstack(tup):

ValueError: all the input array dimensions except for the concatenation axis must match exactly

Интересно, что я попытался напечатать dtype X, и это сработало нормально:

X.dtype => float64

Однако, пытаясь напечатать dtype AllAlexaAndGoogleInfo следующим образом:

print "AllAlexaAndGoogleInfo.dtype => " + str(AllAlexaAndGoogleInfo.dtype) 

производит:

'DataFrame' object has no attribute 'dtype'

Ответы

Ответ 1

Поскольку X - разреженный массив, вместо numpy.hstack, используйте scipy.sparse.hstack для объединения массивов. По-моему, сообщение об ошибке вводит в заблуждение.

Этот минимальный пример иллюстрирует ситуацию:

import numpy as np
from scipy import sparse

X = sparse.rand(10, 10000)
xt = np.random.random((10, 1))
print 'X shape:', X.shape
print 'xt shape:', xt.shape
print 'Stacked shape:', np.hstack((X,xt)).shape
#print 'Stacked shape:', sparse.hstack((X,xt)).shape #This works

На основе следующего вывода

X shape: (10, 10000)
xt shape: (10, 1)

можно ожидать, что hstack в следующей строке будет работать, но факт заключается в том, что он вызывает эту ошибку:

ValueError: all the input arrays must have same number of dimensions

Итак, используйте scipy.sparse.hstack, когда у вас есть разреженный массив для стека.


Фактически, я ответил на это как комментарий в ваших других вопросах, и вы упомянули, что появляется другое сообщение об ошибке:

TypeError: no supported conversion for types: (dtype('float64'), dtype('O'))

Прежде всего, AllAlexaAndGoogleInfo не имеет dtype, так как это DataFrame. Чтобы получить базовый массив numpy, просто используйте AllAlexaAndGoogleInfo.values. Проверьте его dtype. На основе сообщения об ошибке он имеет dtype из object, что означает, что он может содержать не численные элементы, такие как строки.

Это минимальный пример, который воспроизводит эту ситуацию:

X = sparse.rand(100, 10000)
xt = np.random.random((100, 1))
xt = xt.astype('object') # Comment this to fix the error
print 'X:', X.shape, X.dtype
print 'xt:', xt.shape, xt.dtype
print 'Stacked shape:', sparse.hstack((X,xt)).shape

Сообщение об ошибке:

TypeError: no supported conversion for types: (dtype('float64'), dtype('O'))

Итак, проверьте, нет ли каких-либо нечисловых значений в AllAlexaAndGoogleInfo и исправьте их, прежде чем выполнять стекирование.

Ответ 2

Используйте .column_stack. Например:

X = np.column_stack((X, AllAlexaAndGoogleInfo))

Из docs:

Возьмите последовательность 1-D массивов и соедините их как столбцы, чтобы сделать одиночный 2-мерный массив. 2-D массивы складываются как есть, так же, как и с hstack.

Ответ 3

Try:

X = np.hstack((X, AllAlexaAndGoogleInfo.values))

У меня нет работающего модуля Pandas, поэтому он не может его протестировать. Но документация DataFrame описывает values Numpy representation of NDFrame. np.hstack является функцией numpy и как таковая ничего не знает о внутренней структуре DataFrame.