Удаление повторяющихся строк на основе значения столбца

Согласно SourceForge.net Twitter, у них действительно есть катастрофа: SourceForge SF.net Operations @sfnet_ops · Март 3 Мы все еще работаем круглосуточно, чтобы восстановить полную мощность SourceForge. У нас пока нет ETA, но мы обновим здесь, когда будем. Мы ценим Ваше терпение. Спасибо. SourceForge SF.net Operations @sfnet_ops · Март 2 Теперь у нас есть гораздо лучшая идея относительно того, что вызывает недавние проблемы с производительностью. Теперь мы выполняем план, чтобы вернуть SourceForge на полную мощность. У нас может быть несколько часов, но наша команда работает круглосуточно, пока не будет восстановлена ​​стабильность. Спасибо за ваше терпение SourceForge SF.net Operations @sfnet_ops · Мар 1 SourceForge испытывает проблемы. Мы расследуем. SourceForge SF.net Operations @sfnet_ops · 26 февраля Мы все еще работаем над восстановлением полной емкости после сегодняшнего события DDOS. Обновления.

Обновление 1: они SourceForge.net Twitter

SourceForge SF.net Operations @sfnet_ops · Март 3 Мы все еще работаем круглосуточно восстановить полную мощность SourceForge. У нас пока нет ETA, но мы обновим здесь, когда будем. Мы ценим Ваше терпение. Спасибо.

SourceForge SF.net Operations @sfnet_ops · 6:45 AM · 4 марта 2018 г. SourceForge снова в сети.

$ wget -O - http://downloads.sourceforge.net/project/ubuntuzilla/mozilla/apt
--2018-03-04 14:14:46--  http://downloads.sourceforge.net/project/ubuntuzilla/mozilla/apt
Resolving downloads.sourceforge.net (downloads.sourceforge.net)... 216.105.38.13
Connecting to downloads.sourceforge.net (downloads.sourceforge.net)|216.105.38.13|:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2018-03-04 14:14:52 ERROR 404: Not Found.

, но ubuntuzilla все еще unavailable:

$ wget -O - http://downloads.sourceforge.net/corefonts/andale32.exe
--2018-03-04 14:16:46--  http://downloads.sourceforge.net/corefonts/andale32.exe
Resolving downloads.sourceforge.net (downloads.sourceforge.net)... 216.105.38.13
Connecting to downloads.sourceforge.net (downloads.sourceforge.net)|216.105.38.13|:80... connected.
HTTP request sent, awaiting response... 404 Not Found
2018-03-04 14:16:52 ERROR 404: Not Found.

и файлы из ttf-mscorefonts-installer тоже:

SourceForge SF.net Операции @sfnet_ops · 6:12 PM · Март 4, 2018 Проблема, связанная с загрузкой и поиском, была устранена.

Обновление 1: загружено :

2
задан 20 March 2018 в 00:21

9 ответов

Поскольку ввод, по-видимому, сгруппирован / отсортирован по второму столбцу, это должно быть довольно простым и не требует сохранения и сортировки всего набора данных в памяти, только две записи за один раз.1

Сначала я подумал о решении Awk, но нашел его неуклюжим для работы с массивами и непустыми полевыми разделителями. Затем я решил использовать короткую программу Python:

#!/usr/bin/python3
import sys
DELIMITER = ','

def remove_duplicates(records):
    prev = None
    for r in records:
        r = (int(r[0]), int(r[1]), int(r[2]), float(r[3]), int(r[4]))
        if prev is None:
            prev = r
        elif r[1] != prev[1]:
            yield prev
            prev = r
        elif r[3] > prev[3]:
            prev = r
    if prev is not None:
        yield prev

def main():
    for r in remove_duplicates(
        l.rstrip('\n').rsplit(DELIMITER) for l in sys.stdin
    ):
        print(*r, sep=',')

if __name__ == '__main__':
    main()

В моей системе она имеет пропускную способность ~ 250 000 записей или 5 МБ на секунду.

Использование [!d5 ]
python3 remove-duplicates.py < input.txt > output.txt

Программа не может обрабатывать заголовки столбцов, поэтому вам необходимо отключить их:

tail -n +2 < input.txt | python3 remove-duplicates.py > output.txt

Если вы хотите добавить их к результату:

{ read -r header && printf '%s\n' "$header" && python3 remove-duplicates.py; } < input.txt > output.txt

1 Это одно из основных преимуществ над подходами волкатора и стеллара для наборов данных, которые не вписываются в основную память.

1
ответ дан 22 May 2018 в 12:29
  • 1
    waltinator не хранит весь набор данных в памяти, обрабатывает записи, не отсортированные по Cell_Id, и не путается с первым заголовком. – waltinator 20 March 2018 в 02:22
  • 2
    Это сработало! Огромное спасибо. Я выбрал этот ответ, поскольку я знаю немного питона, и этот подход имел смысл для меня и работал как волшебство! Еще одна причина для выбора этого ответа: у меня нет ограничений памяти, поскольку я работаю над кластером :) – Sami 20 March 2018 в 04:24

Поскольку ввод, по-видимому, сгруппирован / отсортирован по второму столбцу, это должно быть довольно простым и не требует сохранения и сортировки всего набора данных в памяти, только две записи за один раз.1

Сначала я подумал о решении Awk, но нашел его неуклюжим для работы с массивами и непустыми полевыми разделителями. Затем я решил использовать короткую программу Python:

#!/usr/bin/python3 import sys DELIMITER = ',' def remove_duplicates(records): prev = None for r in records: r = (int(r[0]), int(r[1]), int(r[2]), float(r[3]), int(r[4])) if prev is None: prev = r elif r[1] != prev[1]: yield prev prev = r elif r[3] > prev[3]: prev = r if prev is not None: yield prev def main(): for r in remove_duplicates( l.rstrip('\n').rsplit(DELIMITER) for l in sys.stdin ): print(*r, sep=',') if __name__ == '__main__': main()

В моей системе она имеет пропускную способность ~ 250 000 записей или 5 МБ на секунду.

Использование

python3 remove-duplicates.py < input.txt > output.txt

Программа не может обрабатывать заголовки столбцов, поэтому вам необходимо отключить их:

tail -n +2 < input.txt | python3 remove-duplicates.py > output.txt

Если вы хотите добавить их к результату:

{ read -r header && printf '%s\n' "$header" && python3 remove-duplicates.py; } < input.txt > output.txt

1 Это одно из основных преимуществ над подходами волкатора и стеллара для наборов данных, которые не вписываются в основную память.

1
ответ дан 17 July 2018 в 18:30

Поскольку ввод, по-видимому, сгруппирован / отсортирован по второму столбцу, это должно быть довольно простым и не требует сохранения и сортировки всего набора данных в памяти, только две записи за один раз.1

Сначала я подумал о решении Awk, но нашел его неуклюжим для работы с массивами и непустыми полевыми разделителями. Затем я решил использовать короткую программу Python:

#!/usr/bin/python3 import sys DELIMITER = ',' def remove_duplicates(records): prev = None for r in records: r = (int(r[0]), int(r[1]), int(r[2]), float(r[3]), int(r[4])) if prev is None: prev = r elif r[1] != prev[1]: yield prev prev = r elif r[3] > prev[3]: prev = r if prev is not None: yield prev def main(): for r in remove_duplicates( l.rstrip('\n').rsplit(DELIMITER) for l in sys.stdin ): print(*r, sep=',') if __name__ == '__main__': main()

В моей системе она имеет пропускную способность ~ 250 000 записей или 5 МБ на секунду.

Использование

python3 remove-duplicates.py < input.txt > output.txt

Программа не может обрабатывать заголовки столбцов, поэтому вам необходимо отключить их:

tail -n +2 < input.txt | python3 remove-duplicates.py > output.txt

Если вы хотите добавить их к результату:

{ read -r header && printf '%s\n' "$header" && python3 remove-duplicates.py; } < input.txt > output.txt

1 Это одно из основных преимуществ над подходами волкатора и стеллара для наборов данных, которые не вписываются в основную память.

1
ответ дан 23 July 2018 в 19:17

Если вы отсортировали их в порядке убывания 4-го поля, вы могли бы просто взять первое вхождение каждого значения второго поля, используя ассоциативный массив или хеш, например. awk -F, '!seen[$2]++' file или perl -F, -ne 'print $_ unless $seen{$F[1]}++'

При значениях в порядке возрастания это немного сложнее сделать за один эффективный проход - вы можете сделать это (с небольшим количеством настроек), распечатав предыдущие при каждом изменении значения ключа:

awk -F, '
  NR==1 {print; next}        # print the header line
  NR==2 {key=$2; next}       # initialize the comparison
  $2 != key {
    print lastval; key = $2  # print the last (largest) value of the previous key group
  } 
  {lastval = $0}             # save the current line
  END {print lastval}        # clean up
' file
storm_id,Cell_id,Windspeed,Storm_Surge,-1
2,10482422,45,0.4,-1
2,10482423,45,0.43,-1
2,10482424,45,0.49,-1
2,10482425,45,0.52,-1
2,10482426,45,0.64,-1
2,10482427,45,0.73,-1
1
ответ дан 22 May 2018 в 12:29

Если у вас не так много уникальных Cell_ids, вы можете отслеживать уже увиденные в ассоциативном массиве Perl. Если у вас слишком много (и у моего скрипта Perl не хватает памяти), напишите программу C, чтобы сохранить уникальные в битовом поле. Вот Perl.

#!/usr/bin/perl -w
use strict;
my %seen = ();          # key=Cell_ID, value=1
my @cols=();            # for splitting input

while( <> ) {           # read STDIN
  @cols = split ',',$_;
  next if ( defined $seen{$cols[1]}); # skip if we already saw this Cell_Id
  $seen{$cols[1]} = 1;
  print;
}

Вот мой тест:

walt@bat:~(0)$ cat u.dat
storm_id,Cell_id,Windspeed,Storm_Surge,-1
2,10482422,45,0.06,-1
2,10482422,45,0.18,-1
2,10482422,45,0.4,-1
2,10482423,45,0.15,-1
2,10482423,45,0.43,-1
2,10482424,45,0.18,-1
2,10482424,45,0.49,-1
2,10482425,45,0.21,-1
2,10482425,45,0.52,-1
2,10482426,45,0.27,-1
2,10482426,45,0.64,-1
2,10482427,45,0.09,-1
2,10482427,45,0.34,-1
2,10482427,45,0.73,-1
walt@bat:~(0)$ perl ./unique.pl u.dat
storm_id,Cell_id,Windspeed,Storm_Surge,-1
2,10482422,45,0.06,-1
2,10482423,45,0.15,-1
2,10482424,45,0.18,-1
2,10482425,45,0.21,-1
2,10482426,45,0.27,-1
2,10482427,45,0.09,-1
-1
ответ дан 22 May 2018 в 12:29
  • 1
    Неплохо, но, к сожалению, требуется память O (n) в памяти даже для наборов данных, предварительно отсортированных по второму столбцу. Было бы лучше отказаться от информации о прошлых ключах, которые больше не требуются. – David Foerster 20 March 2018 в 02:33
  • 2
    О, и что еще более важно , он не возвращает запись с наибольшим значением в столбце 4 для каждой группы одинаковых значений в столбце 2 . – David Foerster 20 March 2018 в 02:36
  • 3
    У меня более миллиона Cell_ID. Итак, я пойду с другим ответом. большое спасибо – Sami 20 March 2018 в 04:25

Если вы отсортировали их в порядке убывания 4-го поля, вы могли бы просто взять первое вхождение каждого значения второго поля, используя ассоциативный массив или хеш, например. awk -F, '!seen[$2]++' file или perl -F, -ne 'print $_ unless $seen{$F[1]}++'

При значениях в порядке возрастания это немного сложнее сделать за один эффективный проход - вы можете сделать это (с небольшим количеством настроек), распечатав предыдущие при каждом изменении значения ключа:

awk -F, ' NR==1 {print; next} # print the header line NR==2 {key=$2; next} # initialize the comparison $2 != key { print lastval; key = $2 # print the last (largest) value of the previous key group } {lastval = $0} # save the current line END {print lastval} # clean up ' file storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.4,-1 2,10482423,45,0.43,-1 2,10482424,45,0.49,-1 2,10482425,45,0.52,-1 2,10482426,45,0.64,-1 2,10482427,45,0.73,-1
1
ответ дан 17 July 2018 в 18:30

Если у вас не так много уникальных Cell_ids, вы можете отслеживать уже увиденные в ассоциативном массиве Perl. Если у вас слишком много (и у моего скрипта Perl не хватает памяти), напишите программу C, чтобы сохранить уникальные в битовом поле. Вот Perl.

#!/usr/bin/perl -w use strict; my %seen = (); # key=Cell_ID, value=1 my @cols=(); # for splitting input while( <> ) { # read STDIN @cols = split ',',$_; next if ( defined $seen{$cols[1]}); # skip if we already saw this Cell_Id $seen{$cols[1]} = 1; print; }

Вот мой тест:

walt@bat:~(0)$ cat u.dat storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.06,-1 2,10482422,45,0.18,-1 2,10482422,45,0.4,-1 2,10482423,45,0.15,-1 2,10482423,45,0.43,-1 2,10482424,45,0.18,-1 2,10482424,45,0.49,-1 2,10482425,45,0.21,-1 2,10482425,45,0.52,-1 2,10482426,45,0.27,-1 2,10482426,45,0.64,-1 2,10482427,45,0.09,-1 2,10482427,45,0.34,-1 2,10482427,45,0.73,-1 walt@bat:~(0)$ perl ./unique.pl u.dat storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.06,-1 2,10482423,45,0.15,-1 2,10482424,45,0.18,-1 2,10482425,45,0.21,-1 2,10482426,45,0.27,-1 2,10482427,45,0.09,-1
0
ответ дан 17 July 2018 в 18:30

Если вы отсортировали их в порядке убывания 4-го поля, вы могли бы просто взять первое вхождение каждого значения второго поля, используя ассоциативный массив или хеш, например. awk -F, '!seen[$2]++' file или perl -F, -ne 'print $_ unless $seen{$F[1]}++'

При значениях в порядке возрастания это немного сложнее сделать за один эффективный проход - вы можете сделать это (с небольшим количеством настроек), распечатав предыдущие при каждом изменении значения ключа:

awk -F, ' NR==1 {print; next} # print the header line NR==2 {key=$2; next} # initialize the comparison $2 != key { print lastval; key = $2 # print the last (largest) value of the previous key group } {lastval = $0} # save the current line END {print lastval} # clean up ' file storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.4,-1 2,10482423,45,0.43,-1 2,10482424,45,0.49,-1 2,10482425,45,0.52,-1 2,10482426,45,0.64,-1 2,10482427,45,0.73,-1
1
ответ дан 23 July 2018 в 19:17

Если у вас не так много уникальных Cell_ids, вы можете отслеживать уже увиденные в ассоциативном массиве Perl. Если у вас слишком много (и у моего скрипта Perl не хватает памяти), напишите программу C, чтобы сохранить уникальные в битовом поле. Вот Perl.

#!/usr/bin/perl -w use strict; my %seen = (); # key=Cell_ID, value=1 my @cols=(); # for splitting input while( <> ) { # read STDIN @cols = split ',',$_; next if ( defined $seen{$cols[1]}); # skip if we already saw this Cell_Id $seen{$cols[1]} = 1; print; }

Вот мой тест:

walt@bat:~(0)$ cat u.dat storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.06,-1 2,10482422,45,0.18,-1 2,10482422,45,0.4,-1 2,10482423,45,0.15,-1 2,10482423,45,0.43,-1 2,10482424,45,0.18,-1 2,10482424,45,0.49,-1 2,10482425,45,0.21,-1 2,10482425,45,0.52,-1 2,10482426,45,0.27,-1 2,10482426,45,0.64,-1 2,10482427,45,0.09,-1 2,10482427,45,0.34,-1 2,10482427,45,0.73,-1 walt@bat:~(0)$ perl ./unique.pl u.dat storm_id,Cell_id,Windspeed,Storm_Surge,-1 2,10482422,45,0.06,-1 2,10482423,45,0.15,-1 2,10482424,45,0.18,-1 2,10482425,45,0.21,-1 2,10482426,45,0.27,-1 2,10482427,45,0.09,-1
0
ответ дан 23 July 2018 в 19:17
  • 1
    Неплохо, но, к сожалению, требуется память O (n) в памяти даже для наборов данных, предварительно отсортированных по второму столбцу. Было бы лучше отказаться от информации о прошлых ключах, которые больше не требуются. – David Foerster 20 March 2018 в 02:33
  • 2
    О, и что еще более важно , он не возвращает запись с наибольшим значением в столбце 4 для каждой группы одинаковых значений в столбце 2 . – David Foerster 20 March 2018 в 02:36
  • 3
    У меня более миллиона Cell_ID. Итак, я пойду с другим ответом. большое спасибо – Sami 20 March 2018 в 04:25

Другие вопросы по тегам:

Похожие вопросы: