2013-03-15 8 views
-1

je un réseau numpy de la forme suivante:Calculer moyenne des éléments de matrice avec la même « identifiant »

['viola.jpg' '0.81' '1.0693461723' '100'] 
['viola.jpg' '0.44' '1.31469086921' '18'] 
['viola.jpg' '0.8' '3.92096084523' '73'] 
['vlasta.jpg' '0.88' '1.36559123399' '110'] 
['vlasta.jpg' '0.88' '1.88126493001' '45'] 
['vlasta.jpg' '0.76' '1.0510328514' '88'] 

Je veux faire la moyenne pour chaque nouvel identificateur dans la colonne 0 les valeurs dans la colonne 1 et 2. de ce qui précède, je voudrais obtenir quelque chose comme:

['viola.jpg' '0.68' '2.14354'] 
['vlasta.jpg' '0.84' '1.41324'] 

(la dernière colonne est complètement hors de propos ici, il peut être une moyenne des chiffres, un aléatoire d'entre eux, ou complètement à l'écart)

J'ai essayé de le faire - mais il échoue parce que reduceat n'aime pas les types flexibles (mon tableau du formulaire ci-dessus étant « photos »)

pics = pics[pics[:,0].argsort()] 
print pics 
last = pics[:,0] 
w = np.where(last[:-1] != last[1:])[0] + 1 
w = np.concatenate(([0], w, [len(pics)])) #add 0 and last value 
print type(pics), type(w) 
means = np.add.reduceat(pics, w[:-1])/np.diff(w)[:,None] 
+2

-ce que ces listes? Et sont ces chaînes réelles au lieu de chiffres? Aussi, ** qu'avez-vous essayé jusqu'ici? ** –

+2

* les valeurs peuvent ne pas être correctes dans mon exemple *? Ce serait bien si en effet vous saviez à quelles valeurs s'attendre. Aussi - quelles tentatives avez-vous faites pour trouver des solutions à ce problème - sur quoi êtes-vous collé, etc ...? –

+1

ye olde itertools.groupby et probablement une compréhension de liste imbriquée vous mènera loin – YXD

Répondre

1

Je ne sais pas où vous avez obtenu cette liste de chaînes de , mais si elle est d'un fichier, utilisez genfromtxt pour obtenir une belle gamme de numpy de celui-ci, avec les bons types:

import numpy as np 
from StringIO import StringIO # to create example file 
s = """ viola.jpg 0.81 1.0693461723 100 
     viola.jpg 0.44 1.31469086921 18 
     viola.jpg 0.8 3.92096084523 73 
     vlasta.jpg 0.88 1.36559123399 110 
     vlasta.jpg 0.88 1.88126493001 45 
     vlasta.jpg 0.76 1.0510328514 88""" 
f = StringIO(s) # creates example file with content above 
a = np.genfromtxt(f, names = "image, someval, another, someid", dtype=['S12', float, float, int]) 

maintenant, a est un tableau structuré. Vous pouvez accéder aux colonnes en utilisant le nom field: Maintenant

images = np.uniques(a['image']) # gets unique values of the column named 'image' 
b = np.empty(len(images), dtype = a.dtype) 
for i, image in enumerate(images): 
    m = a['image'] == image 
    b[i] = (image,) + tuple(a[m][n].mean() for n in a.dtype.names[1:]) 

:(Peut-être que ce n'est pas beaucoup mieux ... désolé pour l'exagération Cependant, il vaut la peine de vous présenter des tableaux structurés, à regarder.. b:

In [3]: b 
Out[3]: 
array([('viola.jpg', 0.6833333333333332, 2.101665962246667, 63), 
     ('vlasta.jpg', 0.84, 1.4326296718, 81)], 
     dtype=[('image', '|S12'), ('someval', '<f8'), ('another', '<f8'), ('someid', '<i8')]) 

In [4]: b['image'] 
Out[4]: 
array(['viola.jpg', 'vlasta.jpg'], 
     dtype='|S12') 

In [5]: b['someval'] 
Out[5]: array([ 0.68333333, 0.84  ]) 

In [6]: b[1] 
Out[6]: ('vlasta.jpg', 0.84, 1.4326296718, 81) 

In [7]: b[b['image']=='viola.jpg'] 
Out[7]: 
array([('viola.jpg', 0.6833333333333332, 2.101665962246667, 63)], 
     dtype=[('image', '|S12'), ('someval', '<f8'), ('another', '<f8'), ('someid', '<i8')]) 

avec ce que vous commencez avec la question, vous pouvez faire quelque chose comme ceci:

a = np.array([['viola.jpg', '0.81', '1.0693461723', '100'], 
       ['viola.jpg', '0.44', '1.3146908692', '18'], 
       ['viola.jpg', '0.8', '3.9209608452', '73'], 
       ['vlasta.jpg', '0.88', '1.3655912339', '110'], 
       ['vlasta.jpg', '0.88', '1.8812649300', '45'], 
       ['vlasta.jpg', '0.76', '1.0510328514', '88']]) 

uniques = np.uniques(a[:,0]) 
b = np.empty((len(uniques), len(a[0])), dtype = 'S12') 

for i,s in enumerate(uniques): 
    m = a[:,0] == s 
    b[i] = [s] + [a[m,j].astype(float).mean() for j in [1,2]] + [int(a[m,3].astype(float).mean())] 
print b 
#[['viola.jpg' '0.6833333333' '2.1016659622' '64'] 
# ['vlasta.jpg' '0.84' '1.4326296717' '81']] 

Si vous utilisez une meilleure stru de données Il est BEAUCOUP plus facile de garder une trace de ce qui est un float, int, et string. Pour preuve, voir la réponse @ HYRY.

+0

que voulez-vous dire par une structure de données pâte? – TheChymera

+0

Je vais modifier pour afficher un tableau * structuré * – askewchan

+1

J'ai lu mon fichier avec http://paste2.org/p/3169593 et ​​genfromtxt ne fonctionnera pas car AttributeError: l'objet 'list' n'a pas d'attribut 'split' :( – TheChymera

3

Vous pouvez utiliser Pandas faire rapidement:

import pandas as pd 

data=[['viola.jpg', '0.81', '1.0693461723', '100'], 
['viola.jpg', '0.44', '1.31469086921', '18'], 
['viola.jpg', '0.8', '3.92096084523', '73'], 
['vlasta.jpg', '0.88', '1.36559123399', '110'], 
['vlasta.jpg', '0.88', '1.88126493001', '45'], 
['vlasta.jpg', '0.76', '1.0510328514', '88']] 

df = pd.DataFrame(data, dtype=float) 
print df.groupby(0).mean() 

Résultat:

    1   2   3 
0           
viola.jpg 0.683333 2.101666 63.666667 
vlasta.jpg 0.840000 1.432630 81.000000 
+0

OP peut vouloir des chaînes de floats et ints comme le montre l'exemple de sortie ... pas sûr – askewchan

+0

non, je ne veux pas de chaînes spécifiquement. pandas semble merveilleux, mais je ne voudrais pas l'ensemble du module juste pour cette fonction. Merci beaucoup. – TheChymera

Questions connexes