我有一个2D数组:
[[2,1],[2,32],[4,4512],[1,34],[2,323],[2,42],[1,23],[4,123]...]
最后,我想计算均值并得到像[[1,mean],[2,mean],[3,mean] ...]这样的数组,
有没有人有一个好的解决方案?我用过:
for i in range(len(array)):
temp =[]
for j in range(len(array)):
if Table[i][0] == Table[j][0]:
temp.append(Table[j])
然后计算temp
的平均值,但它没有退出效率。
有没有人使用pandas
库来解决问题?
答案 0 :(得分:3)
您应该创建一个字典,收集每个键的所有值(第二项)(第一项)。然后,您可以计算字典中每个条目的平均值。
from __future__ import division # use floating-point division by default
values = [[2,1],[2,32],[4,4512],[1,34],[2,323],[2,42],[1,23],[4,123]]
values_by_key = collections.defaultdict(list)
for k, v in values:
values_by_key[k].append(v)
means = sorted([(k, sum(v) / len(v)) for k, v in values_by_key.items()])
或者,您可以使用groupby
对具有相同键的项目进行分组(请记住先排序)并使用(稍微复杂的)嵌套列表理解。
means = [(k, sum(v)/len(v))
for k, v in ((k, [v[1] for v in vals])
for k, vals in itertools.groupby(sorted(values), key=lambda t: t[0]))]
在这两种情况下,means
最终都为[(1, 28.5), (2, 99.5), (4, 2317.5)]
。 Compexity应该是 O(nlogn)(对于排序;如果不需要排序输出,那么第一种方法的复杂性,使用dict,只是 O(n) )。
就个人而言,我会选择字典方法。虽然另一个可以在"一行"中完成,但是dict更清晰也更快(即使需要排序,因为在这种情况下,排序在合并之后完成,即使用更少的元素)。
答案 1 :(得分:1)
使用pandas和groupby:
df = pd.DataFrame([[2,1],[2,32],[4,4512],[1,34],[2,323],[2,42],[1,23],[4,123]])
df.groupby(0).mean()
1
0
1 28.5
2 99.5
4 2317.5
答案 2 :(得分:0)
您可以使用功能样式来解决此问题
data = [[1, 2], [2, 3], [1, 4], [2, 5], ...]
def make_filter(n):
def filter_n(d):
return d[0] == n
return filter_n
def calculate(n, data):
data_n = filter(make_filter(n), data)
s = reduce(lambda acc, d: acc + d[1], data_n, 0)
n = len(data_n)
if n > 0:
return float(s) / n
else:
raise Exception
然后您调用calculate
函数,并将Exception
替换为合适的函数。
答案 3 :(得分:0)
您可以尝试Counter
和defaultdict
以获得更快的效果,如下所示 -
from collections import Counter,defaultdict
sm = defaultdict(float)
data = [[2,1],[2,32],[4,4512],[1,34],[2,323],[2,42],[1,23],[4,123]]
#generate sum of second elements for all the keys (first elements)
for i in data:
sm[i[0]]+=i[1]
#Count the occurrances of the keys (first occurrances)
c = Counter([i[0] for i in data])
#Produce data
print [[k,sm[k]/c[k]]for k in sm.keys()]
输出 -
[[1, 28.5], [2, 99.5], [4, 2317.5]]
答案 4 :(得分:0)
编辑:用总和替换减少
您可以使用内置地图和缩小功能:
from __future__ import division
array = [[2,1],[2,32],[4,4512],[1,34],[2,323],[2,42],[1,23],[4,123]]
d = dict()
l = list() # result
map(lambda i:(d.setdefault(i[0],[]).append(i[1])), array)
map(lambda key: l.append([key, sum(d[key])/len(d[key])]), d.iterkeys())
print(l)
你会得到:
[[1, 28.5], [2, 99.5], [4, 2317.5]]
说明: 首先,您必须按键对所有值进行分组(在您的情况下,键是嵌套数组的第一个值)。 其次,你必须计算平均值并创建结果数组。