2014-10-06 1 views
1

У меня есть файл данных, и я выполняю несколько операций с данными. Я могу получить решения для всех других операций просто отлично. Я не могу рассчитать только медианную.Простой способ найти медиану

Ввод: Несколько строк из огромного ввода.

00904bcabb02 00904bf7d758 676.0 
0030657cc312 00904b1f1154 120.0 
00306597852d 00904b48a3b6 572.0 
00904b1f1154 00904bcabb02 120.0 
00904b1f1154 00904bf7d758 120.0 
00904b48a3b6 00904ba7a3eb 572.0 
00022d1aa531 0006254f5810 2.0 
00022dac729c 0006254f5810 2.0 
00022dbd5c9e 0006254f5810 2.0 
0006254f5810 0050dad80267 2.0 
0006254f5810 00904be2b271 2.0 
00022d097904 004096f41eb8 20.0 
00022d2d30dd 004096f41eb8 20.0 
004096f41eb8 00904b1e7852 20.0 
00022d1406df 00022d36a6df 8.0 
00022d36a6df 00022d8cb682 8.0 
00022d36a6df 0030654a05fa 8.0 
0004230dd7de 000423cbac29 33.0 
0004231e4f43 000423cbac29 33.0 
0030659b49f1 00904b310619 29.0 

Для каждой пары col[0] col[1] я нахожу частота и соответствующее значение средней величине и Sum. Я пытаюсь найти медиану в наборе pairtime. Я использую numpy.median, но это, похоже, не работает. Любое предложение оценили. Благодаря

Код:

from collections import defaultdict 
import numpy as np 
paircount = defaultdict(int) 
pairtime = defaultdict(float) 
pairper = defaultdict(float) 
timeavg = defaultdict(float) 
timefreq = defaultdict(int) 

#get number of pair occurrences and total time 
with open('Input.txt', 'r') as f, open('Output.txt', 'w') as o: 
    for numline, line in enumerate((line.split() for line in f), start=1): 
     pair = line[0], line[1] 
     paircount[pair] += 1 
     pairtime[pair] += float(line[2]) 
    #timeavg = pairtime[pair]/paircount[pair] 
    #pairper = dict((pair, c * 100.0/numline) for (pair, c) in paircount.iteritems()) 
    for pair, freq in paircount.iteritems(): 
     timeavg = pairtime[pair]/freq 
     med = np.median(np.pairtime[pair]) 
     #print pair[0], pair[1], c, pairper[pair], pairtime[pair] 

     o.write("%s %s %s %.2f %.2f %s \n" % (pair[0], pair[1], freq, pairtime[pair], timeavg, med)) 
print 'done' 

Ошибка:

Traceback (most recent call last): 
    File "pair_one.py", line 20, in <module> 
    med = np.median(np.pairtime[pair]) 
AttributeError: 'module' object has no attribute 'pairtime' 
+1

'dict.iteritems' дает два кортежа' (ключ, значение) ', как вы можете распаковать его на * три * имена? – jonrsharpe

+1

Причиной ошибки является то, что вы префикс 'pairtime' с' np', а NumPy не имеет представления о том, что такое парное время. Если целью является преобразование 'pairtime' в массив NumPy, вы должны написать' np.array (pairtime) '. – juandesant

+0

У вас есть реальный образец ваших входных данных и ожидаемого результата? существует потенциальное решение, избегающее циклов for, что делает ваш алгоритм намного быстрее ... –

ответ

0

Заменить:

med = np.median(np.pairtime[pair]) 

с:

med = np.median(pairtime[pair]) 

pairtime является локальной переменной, а не атрибут numpy.

EDIT

Как @fred S указал, pairtime[pair] содержит только сумму времени, а не всю серию. Раньше я этого не замечал. Поскольку вы рассчитываете много статистических данных из временных рядов, я считаю, что лучший подход состоял бы в том, чтобы сохранить весь временной ряд, а не просто сумму, как @Fred S в своем ответе. Затем вы можете рассчитать все свои статистические данные о временных рядах.

Вот снимок на возможное решение:

from collections import defaultdict 
import numpy as np 
pairtimelist = defaultdict(list) 

with open('Input.txt', 'r') as f, open('Output.txt', 'w') as o: 
    for numline, line in enumerate((line.split() for line in f), start=1): 
     pair = line[0], line[1] 
     pairtimelist[pair].append(float(line[2])) 
    for pair in pairtimelist.iterkeys(): 
     timeavg = np.mean(pairtimelist[pair]) 
     timemed = np.median(pairtimelist[pair]) 
     timesum = np.sum(pairtimelist[pair]) 
     freq = len(pairtimelist[pair]) 

     o.write("%s %s %s %.2f %.2f %s \n" % (pair[0], pair[1], freq, timesum, timeavg, timemed)) 
+0

Это дает мне общую сумму парного времени. Наверное, я не должен устанавливать пару пару здесь. –

+0

Это именно то, что я пытаюсь .. Спасибо! –

+0

У меня есть еще один запрос. Я немного зациклен на других проблемах [dict-and-list-manipulation-python] (http://stackoverflow.com/questions/26401544/dict-and-list-manipulation-python) –

3

Ваша ошибка на самом деле не что-нибудь сделать с медианой, поэтому этот пост должен иметь другое название!

Когда Python говорит need more than 2 values to unpack, посмотрите на строку, на которую он жалуется. Ваша итерация хочет med, pair, freq - другими словами, она хочет три значения за раз, а то, что вы даете, является результатом iteritems(). iteritems() всегда будет давать вам два значения за раз, так как он всегда возвращает (key, val) пар.

Думаю, вам просто нужно удалить med, из вашей петли.

+0

Итак, лучший способ - написать новый цикл 'for' для медианы ?? –

+1

@SitzBlogz, если вы измените 'для med, pair, freq в paircount.iteritems():' with 'для пары, freq в файле parcount.iteritems():' В существующем цикле for также см. Комментарий @jonr ниже ваш вопрос – Llopis

+0

@Llopis Но в этом случае я не могу найти медиану –

1

Медиана означает среднее число массива. Возможно, вы имеете в виду это?

timelist=[] 
for pair, freq in paircount.iteritems(): 
    timeavg = pairtime[pair]/freq 
    parttimeArr=np.array(pairtime[pair]) 
    timelist.append(pairtime[pair]) 
timeArr=np.array(timelist) 
median=np.median(timeArr) 
print median 
+0

Ну, это дает некоторые проводные ответы. –

2

Ваша главная проблема в том, вы передаете в одной плавающей точкой в ​​«средней» функции (pairtime [пара] содержит сумму 3-го значений столбцов для данного c1, c2 пара). Вместо этого вам нужно передать список значений.То, как вы вычислить медиану является:

1) Возьмите список номеров

2) разбирайтесь

3) Выклюй число в точном центре списка. Это медиана.

Вот моя трещина при переписывании. Я не запускал его, поэтому могут возникать проблемы с синтаксисом. Но это должно дать вам общую идею.

from collections import defaultdict 
import numpy as np 
paircount = defaultdict(int) 
pairtime = defaultdict(float) 
pairtimelist = defaultdict(list) 
pairper = defaultdict(float) 
timeavg = defaultdict(float) 
timefreq = defaultdict(int) 

#get number of pair occurrences and total time 
with open('Input.txt', 'r') as f, open('Output.txt', 'w') as o: 
    for numline, line in enumerate((line.split() for line in f), start=1): 
     pair = line[0], line[1] 
     paircount[pair] += 1 
     pairtime[pair] += float(line[2]) 
     pairtimelist[pair].append(pairtime[pair]) 
    #timeavg = pairtime[pair]/paircount[pair] 
    #pairper = dict((pair, c * 100.0/numline) for (pair, c) in paircount.iteritems()) 
    for pair, freq in paircount.iteritems(): 
     timeavg = pairtime[pair]/freq 
     med = np.median(pairtimelist[pair]) 
     #print pair[0], pair[1], c, pairper[pair], pairtime[pair] 

     o.write("%s %s %s %.2f %.2f %s \n" % (pair[0], pair[1], freq, pairtime[pair], timeavg, med)) 
print 'done' 
+0

Это выглядит отлично, но при выполнении проблема такова. Предположим, что у нас есть 3 значения '[268.0,675.0,187.0]' Без сортировки он должен показать «675.0» в качестве медианного значения, и если бы при сортировке должен был отображаться «268.0» как медианное значение. Но это показывает значение «862.0» как медианное значение. –

+1

@SitzBlogz: Я не могу понять ваш комментарий: 'np.median' дает правильную медиану для итерации, и в вашем примере она корректно дает' 268.0'. –

0

Причина ошибки заключается в том, что вы предваряя pairtime с np и NumPy не имеет ни малейшего представления о том, что pairtime есть. Если целью является преобразование pairtime в массив NumPy, вы должны написать np.array(pairtime). Это должно работать, синтаксис мудрый:

from collections import defaultdict 
import numpy as np 
paircount = defaultdict(int) 
pairtime = defaultdict(float) 
pairper = defaultdict(float) 
timeavg = defaultdict(float) 
timefreq = defaultdict(int) 

#get number of pair occurrences and total time 
with open('Input.txt', 'r') as f, open('Output.txt', 'w') as o: 
    for numline, line in enumerate((line.split() for line in f), start=1): 
     pair = line[0], line[1] 
     paircount[pair] += 1 
     pairtime[pair] += float(line[2]) 
    #timeavg = pairtime[pair]/paircount[pair] 
    #pairper = dict((pair, c * 100.0/numline) for (pair, c) in paircount.iteritems()) 
    for pair, freq in paircount.iteritems(): 
     timeavg = pairtime[pair]/freq 
     med = np.median(np.array(pairtime[pair])) 
     # med = np.median(pairtime[pair]) # should work as well without np.array 
     #print pair[0], pair[1], c, pairper[pair], pairtime[pair] 

     o.write("%s %s %s %.2f %.2f %s \n" % (pair[0], pair[1], freq, pairtime[pair], timeavg, med)) 
print 'done' 
+0

Это также возвращает значение 'Sum' вместо' Median' –