我需要找到第一列特定值的同一行中所有列的平均值。所以对于如下表格:
0 11 12 40
1 22 24 92
0 12 13 45
1 24 26 90
2 33 36 138
1 22 24 80
2 36 39 135
0 11 12 46
2 33 36 120
我想要得到的平均值表:
0 11.33333333 12.33333333 43.66666667
1 22.66666667 24.66666667 87.33333333
2 34 37 131
例如,对于值0 .. 我取第二列的平均值(11 + 12 + 11)/ 3,第二列的平均值为(12 + 13 + 12)/ 3,第三列的平均值为(46 + 45 + 40)/ 3
答案 0 :(得分:3)
a = [
[0, 11, 12, 40],
[1, 22, 24, 92],
[0, 12, 13, 45],
[1, 24, 26, 90],
[2, 33, 36, 138],
...
]
def average array, index
array = array.select{|l| l[0] == index}
n = array.length.to_f
array.transpose.drop(1).map {|values| values.inject(0){|s, v| s += v}/n}
end
average(a, 0) # => [11.33333333, 12.33333333, 43.66666667]
立刻拥有所有这些:
array.group_by{|l| l[0]}.map do |k, array|
n = array.length.to_f
[k, array.transpose.drop(1).map {|values| values.inject(0){|s, v| s += v}/n}]
end
# =>
[
[0, [11.33333333, 12.33333333, 43.66666667]],
[1, [22.66666667, 24.66666667, 87.33333333]]
[2, [34.0, 37.0, 131.0]]
]
答案 1 :(得分:2)
data = "0 11 12 40
1 22 24 92
0 12 13 45
1 24 26 90
2 33 36 138
1 22 24 80
2 36 39 135
0 11 12 46
2 33 36 120"
avgs = data.split(/\n/).map{|d| d.split(/\t/)}.group_by{|d| d[0] }.each{|a,b| b.each(&:shift) }.inject({}){|avg, (k, ar)| avg[k] = ar.inject([0,0,0]){|av,(a,b,c)| av[0]+=a.to_f; av[1]+=b.to_f; av[2]+=c.to_f; av}.map{|e| e/ar.size}; avg}
#=> {"0"=>[11.333333333333332, 12.333333333333332, 43.66666666666667], "1"=>[22.666666666666664, 24.666666666666664, 87.33333333333334], "2"=>[34.0, 37.0, 131.0]}
打印它:
avgs.each{|k, arr| puts [k,*arr].join("\t") }
#=> 0 11.333333333333332 12.333333333333332 43.66666666666667
#=> 1 22.666666666666664 24.666666666666664 87.33333333333334
#=> 2 34.0 37.0 131.0
<强> UPD 强>
我已经清理了一下我的方法:
avgs = data.split(/\n/).
map{|d| d.split(/\t/).map(&:to_f)}.
group_by(&:first).
inject({}){|avg, (k, ar)| avg[k] = ar.transpose[1..-1].map{|av| av.inject(:+)/av.size}; avg}
答案 2 :(得分:1)
说你有一张表table = [ [0, 11, 12, 40] , [1, 22, 24, 92] .... [2, 33, 36, 120] ]
我假设该表在一行中有固定数量的元素
first_elements_array = table.map { |line| line[0] }.uniq! #get [0,1,2] from your table
avgs = [] #will contain your [ [0, 11.333, 12.3333, 43.66667], ... ]
for element in first_elements_array
#i need an array with 4 zeros - the number of elements on a line
temp_sum = [0,0,0,0]
count = 0 #number of lines that start with 0, or 1, or 2 etc
#read the lines that start with 0, then 1, then 2 etc
for line in table
if line[0] == element
count += 1
#add in temp_sum the new line found, element by element
(0...line.length).each do |i|
temp_sum[i] += line[i]
end
end
end
line_avg = []
#so, temp_sum contains the sum for one line that starts with 0 or 1 or 2 etc. now calculate the average
for sum in temp_sum
line_avg << sum/count
end
#... and push it in an array
avgs << line_avg
end
这可能会更优雅,所以随意适应它
另外,没有时间测试它,让我知道它是否有效