удалить строки, у которых определенный атрибут меньше или равен 0 - PullRequest
1 голос
/ 22 марта 2012

У меня есть несколько больших текстовых файлов (30 м + строки,> 1 ГБ), которые обрабатываются в ArcGIS после разделения (см. Удаление определенных строк из большого текстового файла в python и порция текстовой базы данныхна N равных блоков и сохраняют заголовок для фона).

Даже после разделения процесс занимает более 3 дней, поэтому я хочу удалить все точки xy, у которых (Rx) значение меньше или равно 0.

У меня нет python для работы над чтением наборов данных txt размером более 500 Мб, поэтому я использовал команды cygwin / SED для начальной очистки данных, а затем python для разбиения файла на части.Поэтому в идеале процесс должен был бы добавить некоторый код в питон (см. Ниже), чтобы он не включал все строки с Rx <= 0. </p>

Latitude    Longitude   Rx  Best_Unit
-16.37617    144.68805  -012.9  7
-16.37617    144.68834  -015.1  7
-16.37617    144.68861  -017.2  7
-16.37617    144.68890  -018.1  7
-16.37617    144.68919  -025.0  7
-16.37617    144.68945  -019.5  7
-16.37617    144.68974  -020.0  7
-16.37617    144.69003  -020.4  7
-16.37617    144.69623   015.3  7
-16.37617    144.69652   015.6  7
-16.37617    144.69679   015.8  7
-16.37617    144.69708   016.0  7
-16.37617    144.70076   005.0  7
-16.37617    144.70103   002.2  7
-16.37617    144.70131  -000.2  7
-16.37617    144.70160  -001.5  7
-16.37617    144.70187  -001.0  7
-16.37617    144.70216   000.7  7
-16.37617    144.70245   002.2  7
-16.37617    144.70273   008.4  7
-16.37617    144.70300   017.1  7
-16.37617    144.70329   017.2  7

Я хочу, чтобы все строки (строки), где Rx> 0, былизаписано в новый текстовый файл.Я также хочу, чтобы столбец Best_Unit был удален.

from itertools import islice

import arcpy, os
#fc = arcpy.GetParameter(0)
#chunk_size = arcpy.GetParameter(1) # number of records in each dataset

fc='cb_vhn007_5.txt'
Name = fc[:fc.rfind('.')]
fl = Name+'.txt'

headers_count = 1
chunk_size = 500000

with open(fl) as fin:
  headers = list(islice(fin, headers_count))

  part = 1
  while True:
    line_iter = islice(fin, chunk_size)
    try:
      first_line = line_iter.next()
    except StopIteration:
      break
    with open(Name+'_%d.txt' % part, 'w') as fout:
      for line in headers:
        fout.write(line)
      fout.write(first_line)
      for line in line_iter:
         ## add something here to check if value after third tab
         ## is >0 and if so then write the row or skip.
        fout.write(line) 

    print "Created part %d" % part
    part += 1

Новый код - первая строка содержит значения Rx.

from itertools import islice

import arcpy, os
#fc = arcpy.GetParameter(0)
#chunk_size = arcpy.GetParameter(1) # number of records in each dataset

fc='cb_vhn007_5.txt'
Name = fc[:fc.rfind('.')]
fl = Name+'.txt'

headers_count = 1
chunk_size = 500000

with open(fl) as fin:
  headers = list(islice(fin, headers_count))

  part = 1
  while True:
    line_iter = islice(fin, chunk_size)
    try:
      first_line = line_iter.next()
    except StopIteration:
      break
    with open(Name+'_%d.txt' % part, 'w') as fout:
      for line in headers:
        fout.write(line)
      fout.write(first_line)
      for line in line_iter:
        if line.split()[2][0:1] != '-':
          #print line.split()[2]
          fout.write(line)

    print "Created part %d" % part
    part += 1

Ответы [ 5 ]

2 голосов
/ 22 марта 2012

Я знаю, что это не Python, но, вероятно, это правильный инструмент для работы:

cat cb_vhn007_5.txt | awk '($3 > 0) {print $0}' > parsedfile
2 голосов
/ 22 марта 2012

Вы можете использовать line.split(), чтобы разбить вашу строку на список, содержащий значение каждого из 4 столбцов.

Например:

line='-16.37617\t144.70329\t017.2\t7'
line.split()
# ['-16.37617', '144.70329', '017.2', '7']

Тогда вы можете либо принудить line[2] (помните, что python - индексирование на основе 0) на число и проверьте, является ли оно> 0:

if float(line.split()[2]) > 0:
    fout.write(line)

Или вы можете просто проверить, есть ли в нем знак минус:

if line.split()[2].find('-') != -1:
    fout.write(line)

Если ваши столбцы могут быть не в том же порядке для каждого текстового файла, вы можете выполнить split() для ваших заголовков, определить, что является Rx, и использовать его вместо 2:

i = headers.split().index('Rx')
# now use line[i]
2 голосов
/ 22 марта 2012

Вероятно, достаточно просто проверить line_iter[24] != '-'.

Т.е. заменить:

fout.write(line)

на

if line_iter[24] != '-':
  fout.write(line)
1 голос
/ 22 марта 2012

Вот скрипт на python, который будет читать файл, содержащий данные, отформатированные в виде четырех разделенных пробелами полей в строке, проверять третье поле и выводить любые строки, третье поле которых является положительным числом с плавающей точкой.

Протестировано на Python 2.7.2.

import re

in_fh = open ("gis.txt","r")
out_fh = open ("outfile.txt","w")

for row in in_fh:
    row = re.sub(' +',',',row) # convert to comma-separated format
    try:
        latitude, longitude, rx, best_unit = row.split(',')
    except ValueError: # row didn't have four fields
        print ("complain - not four fields")
        continue

    try:
        float_rx = float(rx)
    except ValueError: # rx could not be cast to float
        print ("complain - third field not float")
        continue

    if float_rx > 0:
        out_fh.write(latitude + "," + longitude + "," + rx + "\n")
    else:
        pass # discard the row

in_fh.close()
out_fh.close()

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

ПоочередноВы рассматривали возможность использования базы данных?sqlite3 встроен и, вероятно, будет нормально обрабатывать 1 ГБ данных.Тогда вы могли бы получить этот результат, выполнив SELECT * FROM data WHERE rx > 0.

1 голос
/ 22 марта 2012

Строки, которые вы ищете, выглядят примерно так:

if line.split()[2][0:1] != "-"
  fout.write(line)

Это разбивает ввод, просматривает третью запись, просматривает первый символ и пропускает печать строки, если-.

...