web-dev-qa-db-fra.com

Numpy hstack - "ValueError: tous les tableaux d'entrée doivent avoir le même nombre de dimensions" - mais ils le font

J'essaye de joindre deux tableaux numpy. Dans l'un, j'ai un ensemble de colonnes/fonctionnalités après avoir exécuté TF-IDF sur une seule colonne de texte. Dans l'autre, j'ai une colonne/fonctionnalité qui est un entier. J'ai donc lu dans une colonne de données de train et de test, exécuté TF-IDF à ce sujet, puis je veux ajouter une autre colonne entière car je pense que cela aidera mon classificateur à apprendre plus précisément comment il devrait se comporter.

Malheureusement, j'obtiens l'erreur dans le titre lorsque j'essaie d'exécuter hstack pour ajouter cette seule colonne à mon autre tableau numpy.

Voici mon code:

  #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))

Voici la sortie et le message d'erreur:

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

Qu'est-ce qui cause mon problème ici? Comment puis-je réparer cela? Pour autant que je puisse voir, je devrais pouvoir rejoindre ces colonnes? Qu'est-ce que j'ai mal compris?

Je vous remercie.

Éditer :

L'utilisation de la méthode dans la réponse ci-dessous obtient l'erreur suivante:

---------------------------------------------------------------------------
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

Fait intéressant, j'ai essayé d'imprimer le dtype de X et cela a bien fonctionné:

X.dtype => float64

Cependant, essayez d'imprimer le dtype de AllAlexaAndGoogleInfo comme ceci:

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

produit:

'DataFrame' object has no attribute 'dtype'
17
Simon Kiely

Comme X est un tableau clairsemé, au lieu de numpy.hstack, utilisation scipy.sparse.hstack pour rejoindre les tableaux. À mon avis, le message d'erreur est un peu trompeur ici.

Cet exemple minimal illustre la situation:

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

Basé sur la sortie suivante

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

on peut s'attendre à ce que le hstack dans la ligne suivante fonctionne, mais le fait est qu'il renvoie cette erreur:

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

Alors, utilisez scipy.sparse.hstack lorsque vous avez un tableau clairsemé à empiler.


En fait, j'ai répondu à cela comme un commentaire dans vos autres questions, et vous avez mentionné qu'un autre message d'erreur apparaît:

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

Tout d'abord, AllAlexaAndGoogleInfo n'a pas de dtype car c'est un DataFrame. Pour obtenir son tableau numpy sous-jacent, utilisez simplement AllAlexaAndGoogleInfo.values. Vérifiez son dtype. Basé sur le message d'erreur, il a un dtype de object, ce qui signifie qu'il peut contenir des éléments non numériques comme des chaînes.

Voici un exemple minimal qui reproduit cette situation:

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

Le message d'erreur:

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

Donc, vérifiez s'il y a des valeurs non numériques dans AllAlexaAndGoogleInfo et réparez-les, avant de faire l'empilement.

18
YS-L

Utilisation .column_stack. Ainsi:

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

De la docs :

Prenez une séquence de tableaux 1-D et empilez-les en colonnes pour créer un seul tableau 2-D. Les tableaux 2D sont empilés tels quels, comme avec hstack.

11
Drewness

Essayer:

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

Je n'ai pas de module Pandas en cours d'exécution, je ne peux donc pas le tester. Mais la documentation DataFrame décrit values Numpy representation of NDFrame. np.hstack est une fonction numpy, et en tant que telle ne sait rien de la structure interne de DataFrame.

1
hpaulj