KeyError: 0 - при циклическом перемещении по фрейму данных - PullRequest
0 голосов
/ 27 апреля 2020

Заранее спасибо за вашу помощь в этом. Я все еще настолько новичок в этом, что я действительно не знаю, что я делаю. Я пробовал несколько способов сделать это, но я продолжаю получать ошибки. Я пытался использовать iterrows, ilo c, lo c и так далее, но не повезло. Я не понимаю, как получить каждую строку данных и использовать значения в этой строке для отправки электронного письма.

Код:

email_list 
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
|   | Client Name | Staff Name      | Role | Due Date   | Submission ID             | Staff Email   | Generated Due Docs ID            |
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
| 1 | H.Pot       | JohannaNameLast | IP   | 2020-04-01 | H.POT-Johanna-IP-4/1/2020 | xyz@gmail.com | h.potjohannanamelastip2020-04-01 |
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
| 2 | S.Man       | DaveSmith       | TS   | 2020-04-01 | S.MAN-David-TS-4/1/2020   | abc@gmail.com | s.mandabc2020-04-01              |
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
| 3 | S.Man       | LouisLastName   | IP   | 2020-04-01 | S.MAN-Louis-IP-4/1/2020   | def@gmail.com | s.manlouislastnameip2020-04-01   |
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
| 5 | T.Hul       | KellyDLastName  | IP   | 2020-04-01 | T.HUL-Kelly-IP-4/1/2020   | ghi@gmail.com | t.hulkelleydlastnameip2020-04-01 |
+---+-------------+-----------------+------+------------+---------------------------+---------------+----------------------------------+
# Get all the Names, Email Addresses, roles and due dates.
all_clients = email_list['Client Name']
all_staff = email_list['Staff Name']
all_roles = email_list['Role']
#all_types = email_list['Form Type']
all_due_dates = email_list['Due Date']
all_emails = email_list['Staff Email']

for idx in range(len(email_list)):
    # Get each records name, email, subject and message
    client = all_clients[idx]
    staff = all_staff[idx]
    role = all_roles[idx]
    #form_type = all_types[idx]
    due_date = all_due_dates[idx]
    email_address = all_emails[idx]

    # Get all the Names, Email Addresses, roles and due dates.
    subject = f"Your monthly summary was Due on {due_date} Days For {client.upper()}"
    message = f"Hi {staff.title()}, \n\nThe {form_type} is due in {due_date} days for {client.upper()}.  Please turn it in before the due date. \n\nThanks, \n\nJudy"


full_email = ("From: {0} <{1}>\n"
                  "To: {2} <{3}>\n"
                  "Subject: {4}\n\n"
                  "{5}"
                  .format(your_name, your_email, staff, email_address, subject, message))
    # In the email field, you can add multiple other emails if you want
    # all of them to receive the same text
try:
    server.sendmail(your_email, [email_address], full_email)
    print('Email to {} successfully sent!\n\n'.format(email_address))
except Exception as e:
    print('Email to {} could not be sent :( because {}\n\n'.format(email_address, str(e)))

# Close the smtp server
server.close()

Ответы [ 2 ]

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

email_list.iterrows() возвращает итератор, который возвращает индекс, а также строку этого индекса в кадре данных. Таким образом, итерация может быть выполнена следующим образом:

for idx, row in email_list.iterrows():
    # Get each records name, email, subject and message
    client = row['Client Name']
    staff = row['Staff Name']
    role = row['Role']
    #form_type = row['Form Type']
    due_date = row['Due Date']
    email_address = row['Staff Email']

    # Get all the Names, Email Addresses, roles and due dates.
    subject = f"Your monthly summary was Due on {due_date} Days For {client.upper()}"
    message = f"Hi {staff.title()}, \n\nThe {form_type} is due in {due_date} days for {client.upper()}.  Please turn it in before the due date. \n\nThanks, \n\nJudy"

вы можете узнать больше о pandas .DataFrame.iterrows () здесь

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

Плохой шаблон - извлекать все столбцы и затем получать соответствующий элемент из каждой такой переменной (удерживая один столбец).

Используйте скорее следующий шаблон:

for idx, row in email_list.iterrows():
    row.Role
    row['Staff Name']

Если вы не используете idx, вместо этого ставьте _.

Этот вариант намного быстрее, чем ваш. Приведенный выше код фактически выполняет здесь одну итерацию (по строкам), тогда как ваш код выполняет:

  • также одну итерацию по номерам строк,
  • , но затем Ваш код выполняет n поисков для отдельного элемента с определенным индексом в каждом столбце .

Давайте вернемся к моему примеру кода. Существует 2 варианта доступа к элементу текущей строки:

  • row.Role - если имя столбца не содержит "специальных" символов (например, пробелов).
  • row['Staff Name'] - в других (более сложных) случаях.

И причина, по которой вы получаете KeyError: 0 .

Обратите внимание:

  • ваши строки имеют индексы, начинающиеся с 1 (крайний левый столбец без заголовка),
  • , но в вашем l oop idx начинается с 0 ,
  • Доступ к каждой "переменной столбца" на самом деле просто по значению индекса , а не по целочисленной позиции элемента "wanted".

Итак, ошибка возникает при самом первом повороте вашего l oop, когда у вас:

  • есть idx == 0 ,
  • переменная столбца (фактически Series ) не содержит элемент с индексом == 0 .

На самом деле Pandas использует здесь 2 разных имени ( Key и index index ) fo Это одно и то же, поэтому открыто для обсуждения, в какой степени это сообщение доступно для чтения. Вы ничего не можете с этим поделать. Вам просто нужно это знать.

Или, если вы по какой-то причине хотите остаться в соответствии с текущей версией вашего кода, измените только инструкцию для на:

for idx in range(1, len(email_list) + 1):
    ...

Тогда это l oop начнется с idx == 1 , и ошибка не должна возникать, если у вас есть индекс как последовательных чисел, начиная с 1.

Но, как я заметил, ваш индекс:

  • начинается с 1 , 2 и 3 (пока все хорошо) ),
  • но тогда есть "пробел", у вас нет строки с индексом 4 .
...