Как отсортировать текстовый файл построчно - PullRequest
1 голос
/ 14 мая 2019

Мне нужно отсортировать текстовый файл в порядке возрастания.Каждая строка текстового файла начинается с индекса, как показано ниже:

2       0       4         0d 07:00:38.0400009155273
3       0       4         0d 07:00:38.0400009155273
1       0       4         0d 07:00:38.0400009155273   

Результат идеи будет следующим:

1       0       4         0d 07:00:38.0400009155273
2       0       4         0d 07:00:38.0400009155273
3       0       4         0d 07:00:38.0400009155273 

Обратите внимание, этот текстовый файл имеет +3миллион строк, и каждый элемент, естественно, считается строкой.

Я уже некоторое время возился с этим без всякой удачи, поэтому решил, что пришло время проконсультироваться с экспертами.Спасибо за ваше время!

РЕДАКТИРОВАТЬ:

Я использую ОС Windows с Python 3.7 в Spyder IDE.Файл не является CSV, это текстовый файл с разделителями табуляции.Существует вероятность того, что не все показатели присутствуют.Простите за noob-ness, у меня нет большого опыта программирования.

Ответы [ 5 ]

4 голосов
/ 14 мая 2019
fn = 'filename.txt'
sorted_fn = 'sorted_filename.txt'

with open(fn,'r') as first_file:
    rows = first_file.readlines()
    sorted_rows = sorted(rows, key=lambda x: int(x.split()[0]), reverse=False)
    with open(sorted_fn,'w') as second_file:
        for row in sorted_rows:
            second_file.write(row)

Это должно работать для текстового файла с 3+ миллионами строк.Использование int(x.split()[0]) отсортирует первый элемент в каждой строке как целое число

Отредактировано для удаления операторов close ()

0 голосов
/ 14 мая 2019

Вот отредактированная версия совершенно хорошего ответа, который у вас уже есть.Изменения могут быть полезны, когда вы узнаете больше о кодировании.Ключевые моменты:

  • При написании программы часто лучше делать кодирование с небольшой выборкой входных данных (например, файл с 30 строками, а не с 3 миллионами): ваша программа будет работать быстрее;выходные данные отладки будут меньше и более читабельными;а также некоторые другие причины.Таким образом, вместо жесткого кодирования пути к входному файлу (или другим файлам), используйте эти пути к файлам в качестве параметров командной строки, используя sys.argv.

    import sys
    
    in_path = sys.argv[1]
    out_path = sys.argv[2]
    
  • Есливы храните много данных в памяти (достаточно, чтобы заставить вас думать, что вы близки к пределам вашей машины), не создавайте ненужных копий данных.Например, чтобы игнорировать первые несколько строк, не сохраняйте исходные строки в rows, а затем получайте нужные значения, используя rows[2:]: это создает новый список.Вместо этого добавьте условную логику к первоначальному созданию rows (в примере используется понимание списка, но вы можете сделать то же самое в обычном цикле for).И если вам нужно отсортировать эти данные, не используйте sorted(), который создает новый список;вместо этого сортируйте список на месте с помощью rows.sort().

    with open(in_path, 'r') as fh:
        rows = [line for i, line in enumerate(fh) if i > 1]
        rows.sort(key = lambda x: int(x.split(None, 1)[0]))
    
  • Нет причин вкладывать блок with в блок чтения с блоком read.Если у вас нет веской причины для соединения двух разных задач в программе, явно разделите их.Это один из самых важных ключей к написанию лучшего программного обеспечения.

    with open(out_path, 'w') as fh:
        for r in rows:
            fh.write(r)
    
0 голосов
/ 14 мая 2019

Я бы использовал простой .split(' ') для форматирования данных в словарь, который выглядит следующим образом:

my_data = {
 2: ['0', '4', '0d', '07:00:38.0400009155273'],
 3: ['0', '4', '0d', '07:00:38.0400009155273'],
 1: ['0', '4', '0d', '07:00:38.0400009155273']
}

Что вы могли бы затем выполнить итерацию (при условии, что все ключи существуют) как:

for i in range(1, max(list(my_data.keys())) + 1):
    pass # do some computation

Кроме того, вы можете выделить определенное значение, например my_data[1]

Чтобы иметь возможность поместить ваши данные в эту форму, я бы использовал скрипт:

with open("foo.txt", "r") as file:
    in_data = file.readlines()

my_data = {}
for data in in_data:
    split_info = data.split(" ")
    useful_data = [item.strip() for item in split_info[1:] if item != ""]
    my_data.update({split_info[0]: useful_data})

for key in sorted(my_data.keys()):
    print("{}: {}".format(key, my_data[key]))

Какие отпечатки:

1: ['0', '4', '0d', '07: 00: 38.0400009155273 ']

2: ['0', '4', '0d', '07: 00: 38.0400009155273 ']

3: ['0', '4', '0d', '07: 00: 38.0400009155273 ']

0 голосов
/ 14 мая 2019

Используйте панд, это вам очень поможет.Предполагая, что файл является CSV, выполните следующие действия:

import pandas as pd
df = pd.read_csv('to/file', sep='\t', index='Name of column with index')  # Guessing that your file is tab separated
df.sort_index(inplace=True)

Теперь у вас есть информационный фрейм со всей информацией, которая вам нужна.Я бы предложил покопаться в пандах, так как это действительно поможет вам.Вот ссылка для начала https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html

0 голосов
/ 14 мая 2019

Я бы сделал это, прочитав файл на строки, разделив их на пустые места, а затем отсортировав их в соответствии с пользовательским ключом;то есть, если ваш файл назывался "foo.txt":

with open("foo.txt") as file:
    lines = file.readlines()
    sorted(lines, key=lambda line: int(line.split()[0]))

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

Однако я не знаю, какну, это будет работать, учитывая ваш размер файла.Может быть, вам придется разделить содержимое файла на куски, которые вы сортируете по одному, а затем вы можете отсортировать куски.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...