【问题标题】:select multiple rows with unique pairs, and export a random selection, for all possible pairs选择具有唯一对的多行,并为所有可能的对导出随机选择
【发布时间】:2014-06-19 19:04:46
【问题描述】:

我正在处理一个非常大的数据集,并且遇到了一个我以前从未遇到过的独特问题。这是与 GPS 点配对的雷达数据。通过雷达处理,我在数据点之间进行插值以平滑雷达图像以选择视野。导出后,我现在每个实际点都有多个点(注意重复的经纬度条目)。这是插值的产物,而不是真实数据。我想做的是为每对独特的经纬度选择一个条目,然后将其粘贴到一个新的数据框中。我还没有决定是要平均时间还是随机选择,但是在尝试配对独特的配对时我还没有成功。我的困境是每列中有大约 4000 个唯一值,所以一个简单的 for 循环似乎不适合我的需要。下面是我的数据顶部的示例。完整的数据集是 70,000 行。

我精通 Matlab 和 R。所以无论哪个提供更简单的解决方案,我都可以。

TL;DR:选择每个分组的 lat 和 long 对,并将该组的单个条目导出到新文件

line trace  t_d C       lat       long      elev      time depth amplitude
1    0     5 0.08 0 58.809629 -134.19494 1759.6395 60.399998 4.530 202.90558
2    0     6 0.10 0 58.809629 -134.19494 1759.6395 60.279999 4.521 250.44923
3    0     7 0.12 0 58.809629 -134.19494 1759.6398 60.199997 4.515 202.77191
4    0     8 0.14 0 58.809629 -134.19494 1759.6398 60.199997 4.515 137.59879
5    0     9 0.16 0 58.809629 -134.19494 1759.6398 60.079998 4.506  76.98897
6    0    10 0.18 0 58.809629 -134.19494 1759.6398 59.959999 4.497  71.91417
7     0    11 0.20 0 58.809629 -134.194940 1759.6398 60.399998 4.530  -76.34547
8     0    12 0.22 0 58.809629 -134.194939 1759.6401 60.520000 4.539  -71.92880
9     0    13 0.24 0 58.809629 -134.194939 1759.6401 60.639999 4.548  -95.66286
10    0    14 0.26 0 58.809629 -134.194939 1759.6401 60.759998 4.557 -161.85239
11    0    15 0.28 0 58.809629 -134.194939 1759.6401 60.879997 4.566 -256.24988
12    0    16 0.30 0 58.809629 -134.194939 1759.6401 61.000000 4.575 -374.82968
13    0    17 0.32 0 58.809629 -134.194939 1759.6404 61.000000 4.575 -322.71951
14    0    18 0.34 0 58.809629 -134.194939 1759.6404 61.000000 4.575 -270.60934
15    0    19 0.36 0 58.809629 -134.194939 1759.6404 60.879997 4.566 -251.24893

【问题讨论】:

    标签: r matlab data-manipulation data-management


    【解决方案1】:

    MATLAB 实现

    您可以使用 unique 及其 'rows' 选项来选择此类唯一对的第一次出现 -

    %// Assuming mat1 holds all the data
    mat1 = [
    1    0     5 0.08 0 58.809629 -134.19494 1759.6395 60.399998 4.530 202.90558
    2    0     6 0.10 0 58.809629 -134.19494 1759.6395 60.279999 4.521 250.44923
    3    0     7 0.12 0 58.809629 -134.19494 1759.6398 60.199997 4.515 202.77191
    4    0     8 0.14 0 58.809629 -134.19494 1759.6398 60.199997 4.515 137.59879
    5    0     9 0.16 0 58.809629 -134.19494 1759.6398 60.079998 4.506  76.98897
    6    0    10 0.18 0 58.809629 -134.19494 1759.6398 59.959999 4.497  71.91417
    7     0    11 0.20 0 58.809629 -134.194940 1759.6398 60.399998 4.530  -76.34547
    8     0    12 0.22 0 58.809629 -134.194939 1759.6401 60.520000 4.539  -71.92880
    9     0    13 0.24 0 58.809629 -134.194939 1759.6401 60.639999 4.548  -95.66286
    10    0    14 0.26 0 58.809629 -134.194939 1759.6401 60.759998 4.557 -161.85239
    11    0    15 0.28 0 58.809629 -134.194939 1759.6401 60.879997 4.566 -256.24988
    12    0    16 0.30 0 58.809629 -134.194939 1759.6401 61.000000 4.575 -374.82968
    13    0    17 0.32 0 58.809629 -134.194939 1759.6404 61.000000 4.575 -322.71951
    14    0    18 0.34 0 58.809629 -134.194939 1759.6404 61.000000 4.575 -270.60934
    15    0    19 0.36 0 58.809629 -134.194939 1759.6404 60.879997 4.566 -251.24893]
    
    [~,v2,v3] = unique(mat1(:,6:7),'rows')
    out = mat1(v2,:) %// desired output of unique pairs of lat and long values
    

    相反,如果您对此类唯一对的最后一次出现感兴趣,您可以改用它,保持其余代码相同 -

    [~,v2,v3] = unique(mat1(:,6:7),'rows','last')
    

    您还谈到了使用“时间”列的平均值,我相信您可以使用它 -

    valid1 = bsxfun(@eq,unique(v3),v3') %//'
    out(:,9) = sum(bsxfun(@times,mat1(:,9)',valid1),2)./sum(valid1,2) %//' desired output with average values for "time"
    

    【讨论】:

    • 聪明的解决方案,但它不是很有效。输出缺少大量独特的数据。它似乎在精度上还不够远。在决定删除什么之前,你能控制它的外观吗?
    • @Scandela1986 您能否再回来查看一下,因为您似乎对其他解决方案的 cmets 进行了一些更改/更正?
    • @Divaker 我最初在回复中输入错误,但我从来没有让你的代码工作。每次我运行它时,它似乎选择了一组不同的唯一值。它似乎被困在精度上,并且没有走得足够远,它没有选择相同的值。我也承认,虽然我在 matlab 上表现不错,但我通常在 R 中工作,所以当它工作时我倾向于采用 R 解决方案。不过,感谢您为此工作,我一直在堆栈溢出上潜伏很长时间,这是我第一次发布问题。您的及时回复很有帮助。
    • @Scandela1986 真的没关系。你很高兴选择一个对你有用的解决方案,这真的是最重要的事情。祝你好运!
    【解决方案2】:

    我使用了duplicated,其中df 是你的data.frame

    df[!duplicated(df[, c("lat", "long")]),]
    

    如果您要汇总数据,请尝试dplyr。例如,你可以这样做:

    df %>% group_by(lat, long) %>% summarise(time = mean(time))
    

    【讨论】:

    • 您的解决方案几乎是完美的,但它也折腾了一些独特的配对。使用上面的 data.frame,它保留了第 1 行,但抛弃了第 3 行,这与第 1 行和第 2 行不同。有什么方法可以设置这有多挑剔?我查了命令。从最后开始控制这个吗?不是很清楚。
    • 所以你想按纬度、经度、高度分组?你的问题只是说经纬度。在这种情况下,只需将其添加到列列表中。例如,c("lat", "long", "elev")
    • 不,抱歉我不清楚。我想找到唯一的纬度和经度对,并保留每一列,但用相同的经度和经度对折腾重复的行。当我运行它时,它似乎只查看前几位小数,但大多数差异都在小数点后第 6 位和第 7 位。使用上述方法,我想保留第 1、7、8 行。但是当我运行它时,我只得到第 1 行和第 8 行。
    • 哦,我想我发现了错误。一些条目有“0”,而其他条目则省略。这就是绊倒它的区别。让我深入研究一下。谢谢!
    • 这确实有效,我的列相对于我在此处发布的内容发生了变化,并且当我在上面发布时正在查看错误的值。太感谢了!这是一个非常清晰和聪明的解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 2013-10-14
    • 2015-06-19
    • 2016-03-15
    • 2016-05-09
    • 1970-01-01
    相关资源
    最近更新 更多