Использование numpy для фильтрации нескольких символов комментариев

#python #numpy

#python #numpy

Вопрос:

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

 # filename: sample.txt
# Comment 1
# Comment 2
$ Comment 3
1,10
2,20
3,30
4,40
# Comment 4
  

Кажется, я могу удалить только один тип комментариев с помощью следующего кода и не могу найти никакой документации о том, как я мог бы удалить оба.

 import numpy as np
data = np.loadtxt('sample.txt',comments="#") # I need to also filter out '$'
  

Существуют ли какие-либо альтернативные методы, которые я мог бы использовать для достижения этой цели?

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

1. Возможно ли иметь данные и комментарий в одной строке в вашем файле?

2. Нет, этого не произойдет.

Ответ №1:

Просто используйте список для комментариев, например:

 data = np.loadtxt('sample.txt',comments=['#', '$', '@'])
  

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

1. ОН работает на numpy версии 1.14.2! Жаль, что это также не работает с genfromtxt.

Ответ №2:

Я бы создал генератор, который будет игнорировать комментарии, а затем передавать его np.genfromtxt() :

 gen = (r for r in open('sample.txt') if not r[0] in ('$', '#'))
a = np.genfromtxt(gen, delimiter=',')
  

Ответ №3:

в этом случае вам нужно прибегнуть к стандартному циклу python по вводу, например, что-то вроде этого:

 data = []
with open("input.txt") as fd:
    for line in fd:
        if line.startswith('#') or line.startswith('$'):
            continue
        data.append(map(int, line.strip().split(',')))

print data
  

вывод:

 [[1, 10], [2, 20], [3, 30], [4, 40]]
  

Ответ №4:

Поскольку ваши строки содержат либо только комментарий, либо ваши данные, я бы просто прочитал файл, прежде чем обрабатывать его с помощью numpy. Строки комментариев будут уничтожены регулярными выражениями.

 import re
from StringIO import StringIO
import numpy as np
with open('sample.txt', 'r') as f:
    data = re.sub(r's*[#$].*n', '', f.read())
data = np.genfromtxt(StringIO(data), dtype=int, delimiter=',')
  

Это даст вам желаемый массив numpy data . Обратите внимание, что этот подход все равно будет работать, если строка (случайно) начинается с некоторого пробела, за которым следует один из символов комментария.

Ответ №5:

Я просмотрел код numpy.loadtxt, и для комментариев невозможно использовать более одного символа, потому что они используют str.split: https://github.com/numpy/numpy/blob/v1.8.1/numpy/lib/npyio.py#L790

Я думаю, вы могли бы загрузить файл построчно, проверить, содержит ли строка комментарий или нет, а затем передать его в numpy.fromstring .

Ответ №6:

Если вы хотите сохранить полную loadtxt мощность, вы можете просто изменить ее так, чтобы она соответствовала вашим потребностям. Как отметил Дэвид Марек, строка, в которой комментарии удаляются, — это

 line = asbytes(line).split(comments)[0].strip(asbytes('rn'))
  

Становится:

 for com in comments:
    line = asbytes(line).split(com)[0]
line = line.strip(asbytes('rn'))
  

Вам также потребуется изменить L717:

 comments = asbytes(comments)
  

превращается в:

 comments = [asbytes(com) for com in comments]
  

Если вы хотите сохранить полную совместимость,

 if isinstance(comments, basestring):
    comments = [comments]