En gros, j'ai un tas de données où la première colonne est une chaîne (étiquette) et les colonnes restantes sont des valeurs numériques. Je lance le suivant:
data = numpy.genfromtxt('data.txt', delimiter = ',')
Cela lit bien la plupart des données, mais la colonne étiquette devient "nan". Comment puis-je gérer cela?
Par défaut, np.genfromtxt
utilise dtype=float
: c'est pourquoi vos colonnes de chaîne sont converties en NaN car, après tout, elles ne sont pas un nombre ...
Vous pouvez demander à np.genfromtxt
d'essayer de deviner le type réel de vos colonnes en utilisant dtype=None
:
>>> from StringIO import StringIO
>>> test = "a,1,2\nb,3,4"
>>> a = np.genfromtxt(StringIO(test), delimiter=",", dtype=None)
>>> print a
array([('a',1,2),('b',3,4)], dtype=[('f0', '|S1'),('f1', '<i8'),('f2', '<i8')])
Vous pouvez accéder aux colonnes en utilisant leur nom, comme a['f0']
...
Utiliser dtype=None
est un bon truc si vous ne savez pas ce que devraient être vos colonnes. Si vous savez déjà quel type ils devraient avoir, vous pouvez donner une dtype
explicite. Par exemple, dans notre test, nous savons que la première colonne est une chaîne, la seconde un int et nous voulons que la troisième soit un float. Nous utiliserions alors
>>> np.genfromtxt(StringIO(test), delimiter=",", dtype=("|S10", int, float))
array([('a', 1, 2.0), ('b', 3, 4.0)],
dtype=[('f0', '|S10'), ('f1', '<i8'), ('f2', '<f8')])
L'utilisation d'une dtype
explicite est beaucoup plus efficace que d'utiliser dtype=None
et est la méthode recommandée.
Dans les deux cas (dtype=None
ou explicite, non-homogène dtype
), vous vous retrouvez avec un tableau structuré.
[Remarque: avec dtype=None
, l’entrée est analysée une seconde fois et le type de chaque colonne est mis à jour pour correspondre au type le plus large possible: nous essayons d’abord un bool, puis un int, puis un float, puis un complexe, puis nous gardons un chaîne si tout le reste échoue. L'implémentation est plutôt maladroite, en fait. Il y avait eu quelques tentatives pour rendre le type deviner plus efficace (en utilisant regexp), mais rien qui a collé jusqu'à présent]
Si votre fichier de données est structuré comme ceci
col1, col2, col3
1, 2, 3
10, 20, 30
100, 200, 300
alors numpy.genfromtxt
peut interpréter la première ligne en tant qu'en-têtes de colonne à l'aide de l'option names=True
. Avec cela, vous pouvez accéder aux données très facilement en fournissant l'en-tête de colonne:
data = np.genfromtxt('data.txt', delimiter=',', names=True)
print data['col1'] # array([ 1., 10., 100.])
print data['col2'] # array([ 2., 20., 200.])
print data['col3'] # array([ 3., 30., 300.])
Puisque dans votre cas les données sont formées comme ceci
row1, 1, 10, 100
row2, 2, 20, 200
row3, 3, 30, 300
vous pouvez obtenir quelque chose de similaire en utilisant l'extrait de code suivant:
labels = np.genfromtxt('data.txt', delimiter=',', usecols=0, dtype=str)
raw_data = np.genfromtxt('data.txt', delimiter=',')[:,1:]
data = {label: row for label, row in Zip(labels, raw_data)}
La première ligne lit la première colonne (les étiquettes) dans un tableau de chaînes . La deuxième ligne lit toutes les données du fichier, mais supprime la première colonne . être utilisé de la même manière que le tableau structuré que numpy.genfromtxt
crée à l'aide de l'option names=True
:
print data['row1'] # array([ 1., 10., 100.])
print data['row2'] # array([ 2., 20., 200.])
print data['row3'] # array([ 3., 30., 300.])
Vous pouvez utiliser numpy.recfromcsv(filename)
: les types de chaque colonne seront automatiquement déterminés (comme si vous utilisiez np.genfromtxt()
avec dtype=None
) et par défaut delimiter=","
. Il s’agit essentiellement d’un raccourci pour np.genfromtxt(filename, delimiter=",", dtype=None)
que Pierre GM a souligné dans sa réponse.
Pour un jeu de données de ce format:
CONFIG000 1080.65 1080.87 1068.76 1083.52 1084.96 1080.31 1081.75 1079.98
CONFIG001 414.6 421.76 418.93 415.53 415.23 416.12 420.54 415.42
CONFIG010 1091.43 1079.2 1086.61 1086.58 1091.14 1080.58 1076.64 1083.67
CONFIG011 391.31 392.96 391.24 392.21 391.94 392.18 391.96 391.66
CONFIG100 1067.08 1062.1 1061.02 1068.24 1066.74 1052.38 1062.31 1064.28
CONFIG101 371.63 378.36 370.36 371.74 370.67 376.24 378.15 371.56
CONFIG110 1060.88 1072.13 1076.01 1069.52 1069.04 1068.72 1064.79 1066.66
CONFIG111 350.08 350.69 352.1 350.19 352.28 353.46 351.83 350.94
Ce code fonctionne pour mon application:
def ShowData(data, names):
i = 0
while i < data.shape[0]:
print(names[i] + ": ")
j = 0
while j < data.shape[1]:
print(data[i][j])
j += 1
print("")
i += 1
def Main():
print("The sample data is: ")
fname = 'ANOVA.csv'
csv = numpy.genfromtxt(fname, dtype=str, delimiter=",")
num_rows = csv.shape[0]
num_cols = csv.shape[1]
names = csv[:,0]
data = numpy.genfromtxt(fname, usecols = range(1,num_cols), delimiter=",")
print(names)
print(str(num_rows) + "x" + str(num_cols))
print(data)
ShowData(data, names)
Sortie Python-2:
The sample data is:
['CONFIG000' 'CONFIG001' 'CONFIG010' 'CONFIG011' 'CONFIG100' 'CONFIG101'
'CONFIG110' 'CONFIG111']
8x9
[[ 1080.65 1080.87 1068.76 1083.52 1084.96 1080.31 1081.75 1079.98]
[ 414.6 421.76 418.93 415.53 415.23 416.12 420.54 415.42]
[ 1091.43 1079.2 1086.61 1086.58 1091.14 1080.58 1076.64 1083.67]
[ 391.31 392.96 391.24 392.21 391.94 392.18 391.96 391.66]
[ 1067.08 1062.1 1061.02 1068.24 1066.74 1052.38 1062.31 1064.28]
[ 371.63 378.36 370.36 371.74 370.67 376.24 378.15 371.56]
[ 1060.88 1072.13 1076.01 1069.52 1069.04 1068.72 1064.79 1066.66]
[ 350.08 350.69 352.1 350.19 352.28 353.46 351.83 350.94]]
CONFIG000:
1080.65
1080.87
1068.76
1083.52
1084.96
1080.31
1081.75
1079.98
CONFIG001:
414.6
421.76
418.93
415.53
415.23
416.12
420.54
415.42
CONFIG010:
1091.43
1079.2
1086.61
1086.58
1091.14
1080.58
1076.64
1083.67
CONFIG011:
391.31
392.96
391.24
392.21
391.94
392.18
391.96
391.66
CONFIG100:
1067.08
1062.1
1061.02
1068.24
1066.74
1052.38
1062.31
1064.28
CONFIG101:
371.63
378.36
370.36
371.74
370.67
376.24
378.15
371.56
CONFIG110:
1060.88
1072.13
1076.01
1069.52
1069.04
1068.72
1064.79
1066.66
CONFIG111:
350.08
350.69
352.1
350.19
352.28
353.46
351.83
350.94