Загрузка каждой строки текстового файла в виде массива numpy без зацикливания - PullRequest
1 голос
/ 16 апреля 2020

У меня есть наборы данных, содержащие данные для частого извлечения правил, где каждая строка имеет различное количество элементов, таких как

9 10 5
8 9 10 5 12 15
7 3 5

Есть ли способ, которым мы могли бы читать файлы с вышеуказанным содержимым сразу и конвертировать его на numpy array из arrays как np.array (np.array ([

array([array([ 9, 10,  5]), array([ 8,  9, 10,  5, 12, 15]),
       array([7, 3, 5])], dtype=object)

Я столкнулся с функцией numpy.loadtxt, но она не обслуживает различное количество столбцов, как Я хочу. С разным числом столбцов, loadtxt требует упоминания столбцов, которые будут использоваться для чтения данных. Но я хочу прочитать все значения в каждой строке.
Один из способов добиться этого - вручную прочитайте файлы и преобразуйте каждую строку в numpy 'array`, но я не хочу идти по этому пути, потому что фактические наборы данных будут намного больше, чем маленький пример, показанный здесь. Например, я планирую использовать наборы данных из FIMI-репозиторий . Один из примеров данных данные о ДТП .
Редактировать: Я использовал следующий код для достижения желаемого

data = []
# d = np.loadtxt('datasets/grocery.dat')
with open('datasets/accidents.dat', 'r') as f:
    for l in f.readlines():
        ar = np.genfromtxt(StringIO(l))
        data.append(ar)
print(data)
data = np.array(data)
print(data)
* 102 3 * Но это то, чего я хочу избежать: цикл в коде python, потому что потребовалось более четырех минут, чтобы просто прочитать данные и преобразовать его в numpy arrays

1 Ответ

2 голосов
/ 16 апреля 2020
In [401]: txt="""9 10 5 
     ...: 8 9 10 5 12 15 
     ...: 7 3 5 
     ...: 9 10 5 
     ...: 8 9 10 5 12 15 
     ...: 7 3 5 
     ...: 9 10 5 
     ...: 8 9 10 5 12 15 
     ...: 7 3 5""".splitlines()                                                                        

(это приблизительно соответствует тому, что мы получили бы с readlines)

Сбор списка списков является простым, но преобразование строк в числа потребовало бы понимания списка:

In [402]: alist = []                                                                                   
In [403]: for line in txt: 
     ...:     alist.append(line.split()) 
     ...:                                                                                              
In [404]: alist                                                                                        
Out[404]: 
[['9', '10', '5'],
 ['8', '9', '10', '5', '12', '15'],
 ['7', '3', '5'],
 ['9', '10', '5'],
 ['8', '9', '10', '5', '12', '15'],
 ['7', '3', '5'],
 ['9', '10', '5'],
 ['8', '9', '10', '5', '12', '15'],
 ['7', '3', '5']]
In [405]: np.array(alist)                                                                              
Out[405]: 
array([list(['9', '10', '5']), list(['8', '9', '10', '5', '12', '15']),
       list(['7', '3', '5']), list(['9', '10', '5']),
       list(['8', '9', '10', '5', '12', '15']), list(['7', '3', '5']),
       list(['9', '10', '5']), list(['8', '9', '10', '5', '12', '15']),
       list(['7', '3', '5'])], dtype=object)

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

In [406]: alist = [] 
     ...: for line in txt: 
     ...:     alist.append(np.array(line.split(), dtype=int)) 
     ...:      
     ...:                                                                                              
In [407]: alist                                                                                        
Out[407]: 
[array([ 9, 10,  5]),
 array([ 8,  9, 10,  5, 12, 15]),
 array([7, 3, 5]),
 array([ 9, 10,  5]),
 array([ 8,  9, 10,  5, 12, 15]),
 array([7, 3, 5]),
 array([ 9, 10,  5]),
 array([ 8,  9, 10,  5, 12, 15]),
 array([7, 3, 5])]
In [408]: np.array(alist)                                                                              
Out[408]: 
array([array([ 9, 10,  5]), array([ 8,  9, 10,  5, 12, 15]),
       array([7, 3, 5]), array([ 9, 10,  5]),
       array([ 8,  9, 10,  5, 12, 15]), array([7, 3, 5]),
       array([ 9, 10,  5]), array([ 8,  9, 10,  5, 12, 15]),
       array([7, 3, 5])], dtype=object)

Учитывая неправильный характер текста и смешивание длин массивов в результате, альтернативы не так много. Массивы или списки различного размера - довольно хороший показатель того, что быстрые операции с многомерными массивами невозможны.

Мы можем загрузить все числа в виде 1d-массива с помощью:

In [413]: np.fromstring(' '.join(txt), sep=' ', dtype=int)                                             
Out[413]: 
array([ 9, 10,  5,  8,  9, 10,  5, 12, 15,  7,  3,  5,  9, 10,  5,  8,  9,
       10,  5, 12, 15,  7,  3,  5,  9, 10,  5,  8,  9, 10,  5, 12, 15,  7,
        3,  5])

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

...