Более быстрый способ перебора строк CSV? - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть файл CSV, размер которого составляет ~ 28 000 строк x 785 столбцов. Мне нужно 1). выделите столбец header, 2) поместите первый столбец каждой строки в массив labels и 3). превратить оставшиеся 784 столбца каждой строки в матрицу 28x28 и добавить их в мой массив images после преобразования их значений в числа с плавающей точкой.

Есть ли более быстрый способ перебора моего CSV?

    images = np.array([])
    labels = np.array([])

    with open(filename) as training_file:
        reader = csv.reader(training_file, delimiter=',')
        header = np.array(next(reader))

        for row in reader:
            label = row[0] # get each row's label

            pixels = row[1:785] # get pixel values of each row
            pixels = np.array(pixels).astype(float) # transform pixel values to floats
            pixels = pixels.reshape(28,28) # turn into 28x28 matrix

            labels = np.append(labels, np.array(label)) # append to labels array
            images = np.append(images, np.array(pixels)) # append to images array

Ответы [ 4 ]

1 голос
/ 24 апреля 2020

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

x = np.empty((28000,784))

, а затем сохранить каждую строку в каждой строке массива. Обновление массива чрезвычайно быстро и высоко оптимизировано. Когда вы закончите, вы можете изменить форму, x.shape = (28000, 28, 28). Обратите внимание, что форма массива и выделение памяти отключены в numpy, поэтому изменение формы массива ничего не стоит (оно просто обновляет способ доступа к значениям, не перемещает значения вокруг). Это означает, что нет причин изменять форму каждой отдельной строки перед добавлением в массив.

1 голос
/ 24 апреля 2020

Вы бы использовали pandas для чтения вашего CSV-файла.

import pandas as pd
csv_file = pd.read_csv('file.csv')

Доступ к столбцам осуществляется с помощью csv_file.name.

В зависимости от размера данных, вы можете прочитать ваш файл по кусочкам:

import pandas as pd
csv_file = pd.read_csv('file.csv', chunksize=1)

В любом случае, прочитайте pandas документацию , которую я считаю лучшим выходом

0 голосов
/ 24 апреля 2020

Как подсказывают несколько человек:

  • Это вычислительно дорого воссоздавать массивы и постоянно добавлять к ним. Вместо этого я создал пустые массивы в get- go. Это сделало то, что уже было относительно быстрым вычислением, намного быстрее.
    with open(filename) as training_file:
        reader = csv.reader(training_file, delimiter=',')
        header = np.array(next(reader)) # column headers

        row_count = len(list(reader))

        images = np.empty((row_count, 784)) # empty array
        labels = np.empty((row_count,)) # empty array

        for row in reader:
            labels.append(row[0]) # get each row's label
            images.append(row[1:785]) # get pixel values of each row

    labels = labels.astype(float)
    images = images.reshape(-1, 28,28).astype(float)
0 голосов
/ 24 апреля 2020

Итерация занимает почти без времени . Проблема в том, что вы используете крайне неэффективный подход для создания ваших массивов.

Никогда не делайте этого в al oop с numpy.ndarray объектами :

labels = np.append(labels, np.array(label)) # append to labels array
images = np.append(images, np.array(pixels)) # append to images array

Вместо этого создайте списки labels и images:

labels = []
images = []

А затем в вашем l oop, добавьте в список объектов (высокоэффективная операция) :

labels.append(np.array(label)) # append to labels list
images.append(np.array(pixels)) # append to images list

Затем, наконец, после вашего l oop готово, преобразуйте список массивов в массив:

labels = np.array(labels)
images = np.array(images)

Обратите внимание, я не уверен, какова форма окончательных массивов, которые вы ожидаете, вам может понадобиться reshape результат , Ваш подход сгладит окончательный массив с каждым .append, потому что вы не указываете ось ... если это действительно то, что вы хотите, тогда labels.ravel() получит вас в конце

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