Как перебирать словарь фреймов данных на основе строковых значений

У меня есть файл Excel с тремя листами, каждый из которых имеет одинаковую структуру, но содержит разные данные.

  • Первоначально я успешно написал «успех» во всех строках столбца «Манекен», где ИМЯ СТУДЕНТА было «Роберто» или «Леонардо».
  • Теперь я хочу написать «неудача» в одном и том же столбце на каждом листе, где присутствует разное «ИМЯ СТУДЕНТА».
  • До сих пор я пробовал с ELSE, но он работает не так, как ожидалось.
  • Ниже для ясности приведены снимки каждого листа в моем файле Excel вместе с проанализированным исходным OrderedDict.

Мой оригинальный OrderedDict:

{'Sheet_1':     ID      Name  Surname  Grade favourite color    favourite sport  Dummy
 0  104  Eleanor     Rigby      6            blue  American football    NaN
 1  168  Barbara       Ann      8            pink             Hockey    NaN
 2  450    Polly   Cracker      7           black      Skateboarding    NaN
 3   90   Little      Josy     10          orange            Cycling    NaN,
 'Sheet_2':     ID       Name   Surname  Grade favourite color favourite sport  Dummy
 0  106       Lucy       Sky      8          yellow          Tennis    NaN
 1  128    Delilah     Perez      5     light green      Basketball    NaN
 2  100  Christina   Rodwell      3           black       Badminton    NaN
 3   40      Ziggy  Stardust      7             red          Squash    NaN,
 'Sheet_3':     ID   Name   Surname  Grade favourite color favourite sport  Dummy
 0   22   Lucy  Diamonds      9           brown            Judo    NaN
 1   50  Grace     Kelly      7           white       Taekwondo    NaN
 2  105    Uma   Thurman      7          purple      videogames    NaN
 3   29   Lola   McQueen      3             red            Surf    NaN}

Мой фрагмент кода (не пишу «ошибка» для «Микеля Анджело»):

# Importing modules
import openpyxl as op
import pandas as pd
import numpy as np
import xlsxwriter
import openpyxl
from openpyxl import Workbook, load_workbook


# Defining the file path
file_path = r'C:/Users/machukovich/Desktop/stack_2.xlsx'

# Load workbook as openpyxl
reference_workbook = load_workbook(file_path)

# We will mantain the workbook open
wb = reference_workbook.active

# Getting the sheetnames as a list using the sheetnames attribute

sheet_names = reference_workbook.sheetnames
print(sheet_names)

names_list = []
for sheet in reference_workbook.worksheets:
    student_name = sheet['B2'].value
    names_list.append(student_name)
    print(f"Student Name: {student_name}")
    
    
print(f"List of Names: {names_list}")

# Loading the file into a dictionary of Dataframes
dict_of_df = pd.read_excel(file_path, sheet_name=None, skiprows=2)

# Writing the loop itself (it fills all the 'Dummy' columns with zeros in all sheets):
for sheet_name, df in dict_of_df.items():
    if student_name =='Roberto' or  student_name =='Leonardo':
        df['Dummy'] = df['Dummy'].fillna('success')
    else:
        df['Dummy'] = df['Dummy'].fillna('failure')

Снимки:

«student_name» получается из поиска имени в ячейке «B2». Последнее значение для «student_name» — «Леонардо», и в дальнейшем оно никогда не меняется. Затем в строке кода if student_name =='Roberto' or student_name =='Leonardo': проверка критерия «если» для «Леонардо» имеет значение True. Логически True ИЛИ что-либо еще всегда является True, поэтому эта строка всегда будет True, а часть критериев «else» никогда не будет использоваться. Хотите ли вы перебрать имена из строки 4 по 7 в столбце B и установить только соответствующую ячейку в столбце G для успеха/неудачи в зависимости от совпадения имени в B2? или что-то другое?

moken 20.04.2024 02:49

@moken Я не хочу перебирать имена со строки 4 по 7 в столбце B. Мне нужно перебирать ячейку B2 на всех листах. Если B2 = 'Miquel Angelo' , как на втором листе, мне нужно выполнить столбец «Фиктивный» со строкой «сбой». Лучше сказать... если B2 отличается от «Леонардо» или «Роберто», столбец «Фиктивный» должен быть заполнен строкой «Отказ».

machukovich 20.04.2024 15:48
0
2
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, вам не хватает того, что moken упомянуто в первом комментарии. Значение student_name в последний раз считывается с листа 3 и имеет значение Leonardo. Хотя значение student_name добавляется к names_list, этот список не используется. Следовательно, значение student_name остается таким же, как Leonardo в строке if student_name =='Roberto' or student_name =='Leonardo':, когда вы перебираете каждый из листов, и, следовательно, оно будет записывать success только в столбец Dummy. Может быть, вы имели в виду использовать значения из names_list при переборе листов? Что-то вроде приведенного ниже работает для меня так, как и ожидалось, и пишет failure для второго листа:

        index = 0
        for sheet_name, df in dict_of_df.items():
            student_name = names_list[index]
            index += 1
            print(f"Student Name in loop: {student_name}")

            if student_name =='Roberto' or  student_name =='Leonardo':
                df['Dummy'] = df['Dummy'].fillna('success')
            else:
                df['Dummy'] = df['Dummy'].fillna('failure')
            df[['Dummy']].apply(print)

Полный вывод журнала:

[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - ['Sheet_1', 'Sheet_2', 'Sheet_3']
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name: Roberto
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name: Miquel Angelo
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name: Leonardo
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - List of Names: ['Roberto', 'Miquel Angelo', 'Leonardo']
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name in loop: Roberto
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - 0    success
1    success
2    success
3    success
Name: Dummy, dtype: object
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name in loop: Miquel Angelo
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - 0    failure
1    failure
2    failure
3    failure
Name: Dummy, dtype: object
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - Student Name in loop: Leonardo
[2024-04-20, 22:31:09 UTC] {logging_mixin.py:151} INFO - 0    success
1    success
2    success
3    success
Name: Dummy, dtype: object

Очень ценю ваш ответ. Но это не совсем то, что я искал. Возможно, мой вопрос был недостаточно ясен.

machukovich 25.04.2024 10:40
Ответ принят как подходящий

Я удалил часть, в которой был создан список значений B2. Для большей ясности. Вот решение, которое я искал:

# Importing modules
import pandas as pd
from openpyxl import load_workbook

# Defining the file path
file_path = r'C:/Users/machukovich/Desktop/stack_2.xlsx'

# Load workbook as openpyxl
reference_workbook = load_workbook(file_path)

# Loading the file into a dictionary of DataFrames
dict_of_df = pd.read_excel(file_path, sheet_name=None, skiprows=2)

# Iterating through each sheet and filling the 'Dummy' column based on student names
for sheet_name, df in dict_of_df.items():
    student_name = reference_workbook[sheet_name]['B2'].value
    df['Dummy'] = 'success' if student_name in ['Roberto', 'Leonardo'] else 'failure'

Спасибо всем, кто пытался мне помочь.

Другие вопросы по теме