2013-03-15 3 views
-1

У меня есть Numpy массив следующего вида:Вычислить среднее из элементов в массиве с одинаковым «идентификатором»

['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'] 

Хочу в среднем для каждого нового идентификатора в столбце 0 значения в колонке 1 и 2. Исходя из вышеизложенного, я хотел бы получить что-то вроде:

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

(последний столбец полностью здесь неуместна, это может быть среднее из чисел, случайный один из них, или полностью налево вне)

Я пытался сделать это, - но он не потому, что reduceat не любит гибкие типов (мой массив данной формы является «фото»)

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

ли эти списки? И эти фактические строки вместо чисел? Кроме того, ** что вы пробовали до сих пор? ** –

+2

* значения могут быть неверными в моем примере *? Было бы хорошо, если бы вы действительно знали, какие значения ожидать. Также - какие попытки вы предприняли при исследовании решений этого вопроса - что конкретно вы застряли и т. Д.? –

+1

ye olde itertools.groupby и, вероятно, вложенное понимание списка даст вам далеко – YXD

ответ

1

Я понятия не имею, где вы получили этот список строк из , но если это из файла, используйте genfromtxt, чтобы получить хороший массив Numpy от него, с правильными типами:

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

Теперь a представляет собой структурированный массив. Вы можете получить доступ к столбцам, используя field имя:

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:]) 

:(Может быть, это не то, что гораздо лучше ... извини за преувеличение, однако, это стоит того, чтобы познакомить вас с структурированными массивами Теперь, чтобы посмотреть на.. 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')]) 

Учитывая то, что вы начинаете с в вопросе, вы можете сделать что-то вроде этого:

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

Если вы используете более STRU данных cture намного проще отслеживать, что такое float, int и string. Для доказательства см. Ответ @ HYRY.

+0

, что вы подразумеваете под структурой данных теста? – TheChymera

+0

Я отредактирую, чтобы показать * структурированный * массив – askewchan

+1

Я прочитал свой файл с http://paste2.org/p/3169593, а genfromtxt не будет работать, потому что AttributeError: объект «list» не имеет атрибута «split» :( – TheChymera

3

Вы можете использовать панд, чтобы сделать это быстро:

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

Результат:

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

OP может захотеть, чтобы строки с плавающей точкой и ints отображались на примере ... – askewchan

+0

нет, мне не нужны строки конкретно. pandas звучит замечательно, но я бы не требовал всего модуля только для этой одной функции. Большое спасибо. – TheChymera

Смежные вопросы