2010-10-06 10 views
0

J'ai un tableau numpy:Numpy - pourquoi erreur de valeur pour NaN lorsque vous essayez de supprimer des lignes

A = array([['id1', '1', '2', 'NaN'], 
      ['id2', '2', '0', 'NaN']]) 

J'ai aussi une liste:

li = ['id1', 'id3', 'id6'] 

Je souhaite itérer sur le tableau et la liste et où le premier élément dans chaque ligne du tableau ne figure pas dans la liste, puis supprimez cette ligne entière du tableau.

Mon code à ce jour:

from numpy import * 

for row in A: 
    if row[0] not in li: 
     delete(A, row, axis = 0) 

Cela renvoie l'erreur suivante:

ValueError: invalid literal for int() with base 10: 'NaN' 

Le type de tous les éléments de chaque ligne est str(), donc je ne comprends pas cette mention int() dans l'erreur.

Des suggestions?

Merci, S ;-)

Répondre

5

générer Juste un nouveau tableau est aucune option?

numpy.array([x for x in A if x[0] in li]) 
+0

Oui, beaucoup plus simple que ma solution! – eumiro

+0

Je pense que l'affiche originale voulait conserver les lignes où 'row [0]' était dans 'li', il faut éliminer' not 'de la condition dans votre liste de compréhension. – dtlussier

+0

@dtlussier: merci d'avoir signalé mon erreur. :) – atomocopter

2

Il semble que vous voulez supprimer une ligne de votre tableau en place, cependant, cela est pas possible en utilisant la fonction np.delete, comme une telle opération va à l'encontre de la façon dont Python et Numpy gérer Mémoire.

J'ai trouvé un post intéressant sur la liste de diffusion Numpy (Travis Oliphant, [Numpy-discussion] Deleting a row from a matrix) où la fonction np.delete est d'abord discuté:

So, "in-place" deletion of array objects would not be particularly useful, because it would only work for arrays with no additional reference counts (i.e. simple b=a assignment would increase the reference count and make it impossible to say del a[obj]).

....

But, the problem with both of those approaches is that once you start removing arbitrary rows (or n-1 dimensional sub-spaces) from an array you very likely will no longer have a chunk of memory that can be described using the n-dimensional array memory model.

Si vous jetez un oeil à la documentation np.delete (http://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html), nous pouvons voir que la fonction renvoie un nouveau tableau avec les parties souhaitées (pas nécessairement les lignes) supprimées.

Definition:  np.delete(arr, obj, axis=None) 
Docstring: 
Return a new array with sub-arrays along an axis deleted. 

Parameters 
---------- 
arr : array_like 
    Input array. 
obj : slice, int or array of ints 
    Indicate which sub-arrays to remove. 
axis : int, optional 
    The axis along which to delete the subarray defined by `obj`. 
    If `axis` is None, `obj` is applied to the flattened array. 

Returns 
------- 
out : ndarray 
    A copy of `arr` with the elements specified by `obj` removed. Note 
    that `delete` does not occur in-place. If `axis` is None, `out` is 
    a flattened array. 

Donc, dans votre cas, je pense que vous aurez envie de faire quelque chose comme:

A = array([['id1', '1', '2', 'NaN'], 
      ['id2', '2', '0', 'NaN']]) 

li = ['id1', 'id3', 'id6'] 

for i, row in enumerate(A): 
    if row[0] not in li: 
     A = np.delete(A, i, axis=0) 

A est maintenant coupé vers le bas que vous vouliez, mais rappelez-vous qu'il est un nouveau morceau de mémoire. Chaque fois que np.delete est appelée, une nouvelle mémoire est allouée que le nom A pointera.

Je suis sûr qu'il ya une meilleure façon vectorisée (peut-être en utilisant des tableaux masqués?) Pour savoir quelles lignes supprimer, mais je ne pouvais pas l'obtenir ensemble. Si quelqu'un l'a cependant s'il vous plaît commenter!