如何从具有属性的矩阵中找到5个最接近的数字?

时间:2012-04-26 13:12:17

标签: r matrix

我有一个矩阵如下

`> y
       1         2         3
1  0.8802216 1.2277843 0.6875047
2  0.9381081 1.3189847 0.2046542
3  1.3245534 0.8221709 0.4630722
4  1.2006974 0.8890464 0.6710844
5  1.2344071 0.8354292 0.7259998
6  1.1670665 0.9214787 0.6826173
7  0.9670581 1.1070461 0.7742342
8  0.8867365 1.2160533 0.7024281
9  0.8235792 1.4424190 0.2030302
10 0.8821301 1.0541099 1.2279813
11 1.1958634 0.9708839 0.4297043
12 1.3542734 0.7747481 0.5119648
13 0.4385487 0.3588158 4.9167998
14 0.8530141 1.3578511 0.3698620
15 0.9651803 0.8426226 1.6132899
16 0.8854192 1.2272616 0.6715839
17 0.7779642 0.8132233 2.3386331
18 0.9936722 1.1629110 0.5083558
19 1.1235897 1.0018480 0.5764672
20 0.7887222 1.3101684 0.7373181
21 2.2276176 0.0000000 0.0000000`

我找到了一条线索,但它可以为整个矩阵提供位置,`

  

n< -read.table(file.choose(),header = T)

     

y< -n [,c(“1”,“2”,“3”)]

     

my.number = 1.12270420185886。

     

z,其中; -abs(Y-my.number)==分钟(ABS(Y-my.number))   其中(Z)   [1] 19`

我想找到至少5个最接近的字母和字母&列也没有,换句话说,我想要矩阵中5个最接近的单个值及其位置。

1 个答案:

答案 0 :(得分:2)

我不知道它是什么语言;是吗?

在过程语言中,我将所有值保存到地图(val,(pos))=(val(row,col); example(0.880 ..->(1,1)),然后按排序价值。

然后迭代i< -pos(1到map.size-5),得到diff(pos(i),pos(i + 5)),搜索最小值(diff),得到值和他们的立场。

以下是Scala中的解决方案:

val matrix = """1  0.8802216 1.2277843 0.6875047
2  0.9381081 1.3189847 0.2046542
3  1.3245534 0.8221709 0.4630722
4  1.2006974 0.8890464 0.6710844
5  1.2344071 0.8354292 0.7259998
6  1.1670665 0.9214787 0.6826173
7  0.9670581 1.1070461 0.7742342
8  0.8867365 1.2160533 0.7024281
9  0.8235792 1.4424190 0.2030302
10 0.8821301 1.0541099 1.2279813
11 1.1958634 0.9708839 0.4297043
12 1.3542734 0.7747481 0.5119648
13 0.4385487 0.3588158 4.9167998
14 0.8530141 1.3578511 0.3698620
15 0.9651803 0.8426226 1.6132899
16 0.8854192 1.2272616 0.6715839
17 0.7779642 0.8132233 2.3386331
18 0.9936722 1.1629110 0.5083558
19 1.1235897 1.0018480 0.5764672
20 0.7887222 1.3101684 0.7373181
21 2.2276176 0.0000000 0.0000000"""

// split block of text into lines
val lines=matrix.split ("\n")
// split lines into words
val rows = lines.map (l => l.split (" \\+"))
// remove the index from the beginning (1, 2, ... 21) and 
// transform values from Strings to double numbers
// triples is: Array(Array(0.8802216, 1.2277843, 0.6875047), Array(0.9381081, 1.3189847, 0.2046542),
val triples = rows.map (_.tail).map(triple=> triple.map (_.toDouble))
// generate an own index for the rows and columns 
// elems is: elems: Array[Array[(Double, (Int, Int))]] = Array(Array((0.8802216,(0,0)), (1.2277843,(0,1)), (0.6875047,(0,2))), Array((0.9381081,(1,0)), ...
val elems = triples.zipWithIndex.map {t=> t._1.zipWithIndex.map (vc=> (vc._1 -> (t._2, vc._2)))}
// sorted = Array((0.0,(20,1)), (0.0,(20,2)), (0.2030302,(8,2)), (0.2046542,(1,2)), 
val sorted = elems.sortBy (e => e._1)
// delta5 = List(0.3588158, 0.369862, 0.2266741, 0.2338945, 0.10425639999999997, 0.1384938,
val delta5 = sorted.sliding (5, 1).map (q => q(4)._1-q(0)._1).toList
val minindex = delta5.indexOf (delta5.min) // minindex: Int = 29, delta5.min = 0.008824799999999966

// we found the smallest intervall of 5 values beginning at 29: 
(29 to 29 +5).map (sorted (_)) 
res568: scala.collection.immutable.IndexedSeq[(Double, (Int, Int))] = 
    Vector( (0.8802216,(0,0)), 
        (0.8821301,(9,0)), 
        (0.8854192,(15,0)), 
        (0.8867365,(7,0)), 
        (0.8890464,(3,1)), 
        (0.9214787,(5,1)))

由于Scala从0到20和0到2计数,其中索引分别从1到3和1到21,你必须在每个位置添加(1,1)=> (1,1),(10,1),等等。