【问题标题】:Simple way to find median求中位数的简单方法
【发布时间】:2014-10-06 14:23:50
【问题描述】:

我有一个数据文件,我对数据执行了一些操作。我可以很好地获得所有其他操作的解决方案。我无法仅计算中位数。

输入:来自大量输入的几行。

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],我找到了频率和相应值的平均值和总和。我试图在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'

【问题讨论】:

  • dict.iteritems 给出了两个元组(key, value),你怎么能把它解压成三个名字?
  • 这个错误的原因是你在pairtime前面加上了np,而NumPy不知道pairtime是什么。如果打算将 pairtime 转换为 NumPy 数组,则应编写 np.array(pairtime)
  • 您有输入数据的真实样本和预期结果吗?有一个潜在的解决方案可以避免 for 循环,从而使您的算法更快......
  • @SaulloCastro 这里包含的输入数据是真实数据的一部分。

标签: python numpy dictionary median


【解决方案1】:

你的错误实际上与中位数无关,所以这篇文章应该有一个不同的标题!

当 Python 显示 need more than 2 values to unpack 时,请查看它所抱怨的行。您的迭代需要med, pair, freq - 换句话说,它一次需要三个值,而您给它的是iteritems() 的结果。 iteritems() 总是会一次给你两个值,因为它总是返回 (key, val) 对。

我认为您只需从 for 循环中删除 med,

【讨论】:

  • 所以更好的方法是为中位数写一个新的for循环??
  • @SitzBlogz,如果您将 for med, pair, freq in paircount.iteritems(): 更改为 for pair, freq in paircount.iteritems(): 在现有的 for 循环中,另请参阅问题下方 @jonr 的评论
  • @Llopis 但在那种情况下我找不到中位数
  • 不,您不需要变量,直到您为其分配一些值。试试看,你会发现
  • 如果我从 for 循环中删除 med 并仍然尝试找到 median 我收到此错误:Traceback (most recent call last): File "pair_one.py", line 20, in &lt;module&gt; med = np.median(np.pairtime[pair]) AttributeError: 'module' object has no attribute 'pairtime'
【解决方案2】:

您的主要问题是您将单个浮点传递给“中位数”函数(pairtime[pair] 包含给定 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'

【讨论】:

  • 这看起来不错,但执行时问题是......假设我们有 3 个值 [268.0,675.0,187.0] 没有排序它应该显示 675.0 作为中值,如果它是排序应该显示 @987654324 @ 作为中值。但这将862.0 显示为中值。
  • @SitzBlogz:我无法理解您的评论:np.median 给出了可迭代的正确中位数,在您的示例中,它正确给出了 268.0
【解决方案3】:

中位数表示数组的中间数。也许你是这个意思?

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

【讨论】:

  • 这给出了一些有线的答案。
【解决方案4】:

替换:

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

与:

med = np.median(pairtime[pair])

pairtime 是一个局部变量,而不是 numpy 属性。

编辑

正如@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))

【讨论】:

  • 这给了我总配对时间的总和。我想我不应该把 pairtime[pair] 放在这里。
  • 这正是我想要的......谢谢!!
  • 我还有一个要求。我有点陷入另一个问题dict-and-list-manipulation-python
【解决方案5】:

错误的原因是你在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'

【讨论】:

  • 这也返回Sum值而不是Median
猜你喜欢
  • 2011-09-05
  • 2010-11-20
  • 1970-01-01
  • 2022-12-11
  • 2011-05-20
相关资源
最近更新 更多