выберите несколько строк с уникальными парами и экспортируйте случайный выбор для всех возможных пар

#r #matlab #data-manipulation #data-management

#r #matlab #манипулирование данными #управление данными

Вопрос:

Я работаю с очень большим набором данных, и у меня есть уникальная проблема, с которой я раньше не сталкивался. Это данные радара в паре с точками GPS. с помощью радиолокационной обработки я произвел интерполяцию между точками данных, чтобы сгладить радиолокационное изображение для выбора горизонтов. после экспорта у меня теперь есть несколько точек для каждой фактической точки (обратите внимание на повторяющиеся записи lat и long). это артефакт этой интерполяции, а не реальные данные. что я хотел бы сделать, так это выбрать одну запись для каждой уникальной пары широты и длины и вставить ее в новый фрейм данных. Я еще не решил, хочу ли я усреднять время или выбирать случайным образом, но я не добился успеха в попытке объединить уникальные пары. моя дилемма заключается в том, что в каждом столбце ~ 4000 уникальных значений, поэтому простой цикл for, похоже, не соответствует моим потребностям. образец верхней части моих данных приведен ниже. полный набор данных составляет 70 000 строк.

Я прилично разбираюсь в Matlab и R. так что то, что обеспечивает более простое решение, меня устраивает.

TL;DR: выберите каждую сгруппированную пару широты и длины и экспортируйте одну запись для этой группы в новый файл.

 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
 

Ответ №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"
 

Комментарии:

1. Умное решение, но оно не совсем работает. на выходе отсутствовали большие массивы данных, которые являются уникальными … похоже, они недостаточно точны. можете ли вы контролировать, как далеко он выглядит, прежде чем решить, что удалить?

2. @Scandela1986 Не могли бы вы проверить еще раз, потому что, похоже, вы внесли некоторые изменения / исправления, просмотрев свои комментарии для другого решения?

3. @Divaker я изначально неправильно ввел свой ответ, но я так и не смог заставить ваш код работать .. каждый раз, когда я его запускал, он, кажется, выбирает другой набор уникальных значений. казалось, что он застрял на точности, и, не заходя достаточно далеко, он не выбирал одинаковые значения. Я также признаю, что, хотя я неплохо разбираюсь в matlab, я обычно работаю на R, поэтому я был предрасположен к принятию решения R, когда оно работало. Спасибо за работу над этим, хотя я долгое время скрывался от переполнения стека, и это был мой первый раз, когда я отправлял вопрос. ваш быстрый ответ был очень полезен.

4. @Scandela1986 На самом деле все в порядке. Вы были добры, что выбрали решение, которое сработало для вас, — это действительно самое главное. Удачи!

Ответ №2:

Я использовал duplicated where df is your data.frame :

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

Если вы собираетесь агрегировать данные, попробуйте dplyr . например, вы могли бы сделать что-то вроде этого:

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

Комментарии:

1. Ваше решение было почти идеальным, но оно также отбрасывает некоторые уникальные пары. Используя приведенный выше data.frame, он сохранил строку 1, но выбросил строку 3, которая отличается от строк 1 и 2. есть ли способ установить, насколько это придирчиво? я посмотрел на команду. контролирует ли это from last? это не очень понятно.

2. итак, вы хотите сгруппировать по широте, длине и высоте? в вашем вопросе только что были указаны широта и долгота. в этом случае просто добавьте его в список столбцов. например, c("lat", "long", "elev")

3. нет, извините, я не понял. я хочу найти уникальные пары lat и long и сохранить каждый столбец, но добавить повторяющиеся строки с той же парой lat и long. когда я запускал его, казалось, что он смотрит только на первые несколько десятичных знаков, но большинство различий находятся в 6-м и 7-м десятичных знаках. используя вышесказанное, я бы хотел сохранить строки 1, 7, 8. но когда я его запускаю, я получаю только строки 1 и 8.

4. о, кажется, я нашел ошибку. некоторые записи имеют «0», а другие опущены. в том-то и разница, что это срабатывает. позвольте мне немного углубиться в это. Спасибо!

5. Это действительно сработало, мои столбцы были сдвинуты по отношению к тому, что я опубликовал здесь, и просматривал неправильные значения, когда я публиковал выше. большое вам спасибо! это было очень четкое и умное исправление.