Python для устранения строк, n-й столбец которых не существует в m-м столбце другого файла

#python #csv

#python #csv

Вопрос:

У меня есть два текстовых файла с разделителями табуляции с UTF-8 без спецификации.

1.txt

 A    B    C
X    x    y
T    d    2
  

2.txt

 2   A
3   Y
2   X
  

Команда

python eliminate_rows_in.py 2.txt 2 . 1.txt 1 . output.txt

будет означать: если какой-либо элемент 2-го столбца 2.txt не существует в 1-м столбце 1.txt , исключите строку этого элемента.

Так что output.txt будет

2.txt

 2   A
2   X
  

Я делал это, сортируя эти файлы в соответствующих столбцах в Excel, но затем файл вскоре стал слишком большим.

Честно говоря, я полный новичок в python, поэтому коды, которые я вижу, мне нужны, — это «структурные» части.

 import codecs
import sys
input_file = sys.argv[1]
input_column = sys.argv[2]
match_file = sys.argv[3]
match_column = sys.argv[4]
output_file = sys.argv[5]

ifile = codecs.open(input_file, encoding = 'utf-8', mode="rb")
ofile = codecs.open(output_file, encoding = 'utf-8', mode="wb")

for line in ifile:
????????
ofile.write(line)

ifile.close()
ofile.close()
  

============================================

первое решение martineau выдает

 2   A

2   X
  

вместо

 2   A
2   X
  

Можно ли это исправить?

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

1. возможно, вы захотите проверить argparse и csv.

Ответ №1:

Вы могли бы использовать csv модуль для чтения и записи файлов, но в данном случае это не обязательно, потому что это относительно просто сделать самостоятельно. Обратите внимание, что индексы строк и значений (столбцов) в строке в Python основаны на нуле, поэтому первый столбец соответствует номеру столбца 0 , второй 1 — и т.д. То же самое для строк.

 import codecs
import sys

input_file_name    = sys.argv[1]
input_column_index = int(sys.argv[2]) - 1
match_file_name    = sys.argv[3]
match_column_index = int(sys.argv[4]) - 1
output_file_name   = sys.argv[5]

# create a set of all unique values in the match_column of match_file_name
matching_values = set()
with codecs.open(match_file_name, encoding='utf-8', mode="rb") as match_file:
    for cols in (line.split() for line in match_file):
        matching_values.add(cols[match_column_index])

with codecs.open(output_file_name, encoding='utf-8', mode="wb") as output_file:
    # copy lines from input_file to output file whose value in the input_column
    # is one of the ones in the match column of the match_file
    with codecs.open(input_file_name, encoding='utf-8', mode="rb") as input_file:
        for line in input_file:
            cols = line.split()
            if cols[input_column_index] in matching_values:
                output_file.write(line)
  

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

1. Большое вам спасибо. Ваше решение просто оставляет пустую строку там, где изначально существовала исключенная строка. Я отредактировал свой вопрос, чтобы уточнить, что я имею в виду. Можно ли это исправить?

2. Пустые строки были там, потому что код добавлял ненужную новую строку в строки, которые не были удалены — но моя последняя правка должна это исправить. Я также немного изменил порядок выполнения вещей, чтобы быть более логичным.

3. Если мое последнее обновление устраняет проблему с пустой строкой, пожалуйста, подумайте о принятии моего ответа (см. Как работает принятие ответа? ).

Ответ №2:

Вот кое-что, с чего вы начнете. Это неполно, но, надеюсь, оно поможет вам в правильном направлении.

 import csv

# set stores only unique values to add items use .add(item)
first_column_items = set()
# load 1st column of 1.txt items into first_column_items 
# open 2.txt as infile_two

with open("outfile.txt", "wb") as out_f:
    writer = csv.writer(out_f)
    desired_column_idx = 1 # indexes are zero start
    for row in infile_two:
        column_value = row[desired_column_idx]
        if column_value in first_column_items:
            outfile.writerow(row)