Как получить данные из csv в объект python

Я начинающий пользователь питона. Возникли проблемы с получением данных из csv в python в требуемом формате объекта для удовлетворения функции python. Если я вручную создал данные в python (вместо того, чтобы вводить их из csv), работает следующий код:

class Student(object):
   pass

john = Student()
#score tuple
john.score = (85.0, 42.0/2.0)

bob = Student()
bob.score = (45.0, 19.0/2.0)

john.rank = 1
bob.rank = 2

ExternalCode.AdjustStudents([john, bob])

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

Формат файла csv: john, 85, 21, 1 bob, 45, 9.5, 2.

Студенческие объекты будут иметь атрибут оценки (столбцы 2 и 3 в виде кортежа), а также атрибут ранга (столбец 4). Требуемый формат объекта будет таким же, как созданный кодом вручную выше.

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

print(" John: score1={0[0]:.3f} score2={0[1]:.3f}".format(john.skill)) 

Я получаю этот результат:

Джон: оценка1=25.000 оценка2=8.333

Ваше здоровье,

Стив


person user8891420    schedule 06.11.2017    source источник
comment
Каков требуемый формат объекта? Попробуйте добавить краткий пример данных CSV и покажите, как вы хотите, чтобы данные были представлены при импорте.   -  person andrew_reece    schedule 06.11.2017
comment
Формат файла csv будет следующим:   -  person user8891420    schedule 06.11.2017
comment
Добавьте к вопросу сокращенную версию вашего CSV-файла и желаемый результат.   -  person skrx    schedule 06.11.2017
comment
john, 85, 21, 1, тогда bob будет в том же формате на следующей строке. Все объекты Student будут иметь атрибут оценки (столбцы 2 и 3 в виде кортежа), а также атрибут ранга (столбец 4). Требуемый формат будет таким же, как созданный кодом вручную выше.   -  person user8891420    schedule 06.11.2017
comment
^ Предлагаю добавить эти данные в свой пост.   -  person andrew_reece    schedule 06.11.2017


Ответы (2)


Если я правильно вас понял, вы спрашиваете, как можно динамически создавать переменные. Манипулировать globals() dict для создания новых переменных не очень хорошая идея, и вам лучше использовать список или словарь для хранения ваших данных csv.

Кажется, вам нужен список, поэтому:

  1. Определите список (student_list в примере ниже).
  2. Откройте CSV-файл.
  3. Создайте csv.reader.
  4. Итерация по строкам.
  5. Преобразуйте числа в числа с плавающей запятой.
  6. Создайте экземпляр Student и передайте имя и номера.
  7. Наконец, добавьте этот экземпляр учащегося в файл student_list.

Итак, если ваш CSV-файл выглядит так,

name,score1,score2,rank
john,85,21,1
sarah,72,19,2
bob,45,19,3

попробуйте следующий код:

import csv


class Student:

    def __init__(self, name, score, rank):
        self.name = name
        self.score = score
        self.rank = rank


student_list = []

with open('temp.csv', newline='') as csv_file:
    reader = csv.reader(csv_file)
    next(reader, None)  # Skip the header.
    # Unpack the row directly in the head of the for loop.
    for name, score1, score2, rank in reader:
        # Convert the numbers to floats.
        score1 = float(score1)
        score2 = float(score2)
        rank = float(rank)
        # Now create the Student instance and append it to the list.
        student_list.append(Student(name, (score1, score2), rank))

# Then do something with the student_list.
person skrx    schedule 06.11.2017
comment
Спасибо скркс. Кажется, приближается. Однако, когда я делаю следующий вывод после ручного кода: print( John: score1={0[0]:.3f} score2={0[1]:.3f}.format(john.skill)) я получаю следующее результат: Джон: счет1=25.000 счет2=8.333 Хотя, если я сделаю тот же код печати после кода csv сверху, я получаю: NameError: имя «Джон» не определено. Так что, похоже, он не совсем создает тот же результат. - person user8891420; 06.11.2017
comment
Переменной john больше нет, потому что все экземпляры учащихся теперь находятся в списке. Если вы хотите получить доступ к учащимся по именам, лучше поместить их в словарь вместо списка и получить к ним доступ следующим образом: student_dict['john']. В этом случае класс Student фактически не нужен. - person skrx; 06.11.2017
comment
Спасибо скркс. Основная цель кода — получить вызов функции, который работает с ручными данными, т. е. ExternalCode.AdjustStudents([john, bob]), работающий с динамическим кодом/данными. Если я помещу этот вызов функции в конец вашего кода и вставлю student_list вместо [john, bob], это не сработает. Как бы вы заставили этот вызов функции работать? - person user8891420; 09.11.2017
comment
Вы получаете сообщения об ошибках? Если да, опубликуйте полную трассировку. Кроме того, как работает метод ExternalCode.AdjustStudents? Какие аргументы он принимает? Если он работал со списком ваших переменных (которые являются экземплярами Student), то он должен работать и со списком student_list. - person skrx; 09.11.2017
comment
В ручном коде выше я сделал вызов функции с помощью ExternalCode.AdjustStudents([john, bob]). В то время как с вашим динамическим кодом я использовал ExternalCode.AdjustStudents([student_list]). Сообщение об ошибке, которое я получил, выглядит следующим образом: - person user8891420; 09.11.2017
comment
Трассировка (последний последний вызов): Файл C:\Users\Steve\AppData\Local\Programs\Python\Python36-32\DynamicCode.py, строка 100, в ‹module› ExternalCode.AdjustStudents([student_list]) Файл C: \Users\Steve\AppData\Local\Programs\Python\Python36-32\ExternalCode.py, строка 328, в файле AdjustStudents student.sort(key=lambda p: p.rank) C:\Users\Steve\AppData\Local \Programs\Python\Python36-32\ExternalCode.py, строка 328, в ‹лямбда› student.sort(key=lambda p: p.rank) AttributeError: объект «список» не имеет атрибута «ранг» - person user8891420; 09.11.2017
comment
Верхняя часть функции AdjustStudents выглядит следующим образом (это очень длинная функция, я думаю, что эта часть должна предоставить больше всего информации об ошибке): p: p.rank) ss = [Переменная() для p у студентов] ps = [Переменная() для p у студентов] ts = [Переменная() для p у студентов] ds = [Переменная() для p у студентов[ :-1]] оценка = [PriorFactor(s, Gaussian(mu=pl.score[0], sigma=sqrt(pl.score[1] ** 2 + GAMMA ** 2))) для (s, pl) в почтовом индексе (сс, студенты)] - person user8891420; 09.11.2017
comment
Ошибка в том, что вы помещаете student_list, который уже является списком, в другой список [student_list]. Просто позвоните ExternalCode.AdjustStudents(student_list). - person skrx; 09.11.2017
comment
Спасибо за вашу помощь, skrx, теперь это сработало как шарм! - person user8891420; 10.11.2017

Вы можете прочитать файл csv с помощью pandas.

В пандах есть функция read_csv("filename/filepath"), которая считывает данные из CSV-файла и сохраняет их в виде массива.

person huzaifamansoor    schedule 06.11.2017
comment
Привет, кимкевин, я попробовал панд перед публикацией. Я мог нормально импортировать данные в python, однако все еще испытывал трудности с получением данных в требуемом формате объекта, описанном выше. - person user8891420; 06.11.2017