web-dev-qa-db-fra.com

TypeError: Non concordance entre le type de tableau et le spécificateur de format

J'ai un tableau numpy de dimension 1000 * 30 * 150. J'essaye de l'enregistrer en tant que fichier txt. Jusqu'ici j'ai essayé ceci

np.savetxt("test.txt", mydata, fmt='%.5f', delimiter=",")
#and 
with open('test.txt', 'w') as f:
    for row in mydata:
        np.savetxt(f, row, delimiter=',', fmt='%.5f')

les deux méthodes me donnent une erreur 

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/numpy/lib/npyio.py", line 1254, in savetxt
    fh.write(asbytes(format % Tuple(row) + newline))
TypeError: only length-1 arrays can be converted to Python scalars

During handling of the above exception, another exception occurred:

Traceback (most recent call last):


        np.savetxt("test.txt", train, fmt='%.5f', delimiter=",")
      File "/usr/local/lib/python3.5/dist-packages/numpy/lib/npyio.py", line 1258, in savetxt
        % (str(X.dtype), format))
    TypeError: Mismatch between array dtype ('float64') and format specifier ('%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f,%.5f')
5
Test Test

Vous n'avez pas mentionné le but de l'écriture du tableau 3-D dans un fichier texte, le liriez-vous ultérieurement, et le format recherché, mais c'est une possibilité:

import json
print(json.dumps(mydata, default=lambda x: list(x), indent=4))

Si vous clarifiez le but, les gens seront en mesure de proposer des solutions mieux adaptées.

2
Yigal

Le problème est que votre tableau est en 3 dimensions et ne peut pas être enregistré dans un format en 2 dimensions. Soit le remodeler, pour qu'il soit 2d:

mydata = mydata.reshape(mydata.shape[0],mydata.shape[1]*mydata.shape[2])
np.savetxt('text.txt',mydata,fmt='%.5f',delimiter=',')

ou si vous n'avez pas besoin de le lire sous forme de fichier texte et que vous voulez simplement le recharger plus tard, utilisez python:

np.save('text.npy',mydata)
4
DJK

Parlez-nous de mydata. En particulier ses dtype et shape.

Pour enregistrer au format %.5f, il doit s'agir d'un tableau de nombres en 2D.

savetxt fait à peu près:

 for row in arr:
   print(format % Tuple(row))

format est construit à partir de votre paramètre fmt et du nombre de colonnes du tableau. Il semble que votre tableau comporte un grand nombre de colonnes, alors format correspond à cette chaîne '%.5f,%.5f,%.5f,%.5f,%.5f,%....

Tuple est nécessaire pour transformer ce tableau 1d row en un tuple qui fonctionne avec format%().

Si le tableau a des dimensions supérieures ou un tableau d'objets, des problèmes se poseraient.


edit - si vous dites que le tableau est 1000 * 30 * 150. Donc, il essaie d'itérer sur les 1000 lignes, 30 ressemble à la taille de cette format. Mais il ne peut pas appliquer cela à un tableau (30,150).

Avec les itérations open et row, obtenez-vous la même erreur? Dans Py3, vous devrez peut-être ouvrir avec 'wb'. Iterating yourself on the first dimension means eachsavetxtcall works with a 30x150 array. It will iterate on the 30, and try to format rows of 150. The would create a largerformat`, mais je pense que cela fonctionnerait.

Dans tous les cas, savetxt est conçu pour des tableaux numériques 2d. La 3D nécessite une sorte de fudge. N'oubliez pas non plus que les lecteurs csv ne sont pas non plus conçus pour les tableaux 3D. Ils attendent des lignes avec des colonnes cohérentes séparées par un simple délimiteur.


In [260]: arr = np.arange(24).reshape(4,3,2)

Cela peut fonctionner avec 3d - si on permet de formater chaque subrow avec %s:

In [261]: np.savetxt('test',arr, fmt='%s')
In [262]: cat test
[0 1] [2 3] [4 5]
[6 7] [8 9] [10 11]
[12 13] [14 15] [16 17]
[18 19] [20 21] [22 23]

Format numérique 3d - erreur

In [263]: np.savetxt('test',arr, fmt='%d')
....
TypeError: Mismatch between array dtype ('int32') and format specifier ('%d %d %d')

Remodeler 3D en 2D - sauvegarder les travaux:

In [264]: np.savetxt('test',arr.reshape(-1,2), fmt='%d')
In [265]: cat test
0 1
2 3
4 5
6 7
8 9
...
22 23

Avec une itération supplémentaire; pourrait ajouter une ligne vide entre les blocs

In [267]: with open('test','wb') as f:
     ...:     for row in arr:
     ...:         np.savetxt(f, row, '%d',delimiter=', ')
     ...:         
In [268]: cat test
0, 1
2, 3
4, 5
6, 7
...
22, 23
1
hpaulj

Une alternative à np.savetxt () pourrait utiliser le module csv:

with open("filename.","w+") as my_csv:            # writing the file as my_csv
    csvWriter = csv.writer(my_csv,delimiter=',')  # using the csv module to write the file
    csvWriter.writerows(array_2d)                 # write every row in the matrix

J'ai rencontré un problème similaire avec TypeError avec numpy, mais la méthode CSV semble fonctionner correctement.

0
Larry

Si vous cherchez à écrire les données sous forme de lignes et de colonnes formatées le long de l'axe avec mydata[i,:,:] avec l'intention de produire quelque chose dans un format de tableau plus lisible, voir la réponse suivante: Comment écrire un tableau multidimensionnel dans un fichier texte? par @JoeKington. Mon code ajoute une boucle à travers les lignes et les colonnes de chaque tranche car je ne pouvais trouver aucune autre résolution pour un TypeError que j'obtenais lors de l'implémentation du code d'origine:

    with open('test.txt', 'w') as outfile:
        # Add header giving shape of array
        # Any line starting with "#" will be ignored by numpy.loadtxt
        outfile.write('# Array shape: {0}\n'.format(x_train.shape))

        # Iterating through a ndimensional array produces slices along
        # the last axis. This is equivalent to data[i,:,:] in this case
        sliceCount = 0
        for data_slice in x_train:
            # Keep track of the slice numbers
            outfile.write('# New slice %d\n'%sliceCount)

            # Work through each row and column of the 2d numpy array inside the 
            # slice, writing each column number to file in format of your choosing
            for row in data_slice:
                for col in row:
                    itemStr = "%8.6f,"%col
                    outfile.write(itemStr)
                outfile.write("\n")

            sliceCount += 1
0
humbleHacker