#python #pandas #xlsxwriter
Вопрос:
У меня есть следующий код:
import pandas as pd from datetime import datetime writer = pd.ExcelWriter( f"~/{datetime.today().strftime('%Y.%m.%d')} - Report.xlsx", engine="xlsxwriter", date_format="dd/mm/yyyy", datetime_format="dd/mm/yyyy", ) worksheet = writer.sheets["Sheet1"] comma_format = workbook.add_format( {"num_format": "#,###;[Red](#,###);-", "bold": True} ) worksheet.conditional_format( "$A$2:$J$1000", { "type": "cell", "criteria": "containing", "value": '"Total"', "format": comma_format, }, )
Я хотел бы, чтобы всякий раз, когда строка содержит слово «Всего» в любой ячейке строки, форматировать всю ячейку с comma_format
помощью .
Однако приведенный выше сценарий форматирует только ячейку, содержащую «Всего», а не всю строку.
Есть какие-нибудь идеи о том, как я могу это исправить?
Большое спасибо,
Майк
Комментарии:
1. В общем, вам нужно сначала выяснить, как выполнить сложный условный формат в Excel, а затем перенести его в XlsxWriter. Сказав это, я не думаю, что то, что вы хотите сделать, возможно с помощью одного условного формата. Подход, который вы обычно используете, заключается в использовании условного формата формулы с абсолютной привязкой в строке. Однако этот якорь может находиться только в одном столбце в строке. Таким образом, вам нужно будет воспроизвести условный формат для каждого столбца в строке. Насколько я знаю, это скорее вопрос Excel, чем вопрос на Python.
Ответ №1:
Вы можете использовать операции с кадрами данных для получения индексов строк, содержащих слово Total, например. rows_with_total = df[df.applymap(lambda x: True if isinstance(x, str) and 'total' in x.lower() else False).any(1)].index.to_list()
.
applymap
выполняет итерацию по всем значениям во фрейме данных и применяет переданную функцию к каждому из них. В этом случае он возвращает True
, если значение является строкой и содержит слово total, в противном случае он возвращается False
.
any
Метод с переданным 1 проверяет, есть ли какое-либо значение в строке True
, и возвращает значение a Series
booleans
( True
если есть какой-либо столбец в строке True
и False
в противном случае). Перенос этой части в df [«эта часть»] фильтрует строки, которые возвращаются, на основе Series
boolean
значений.
Затем .index.to_list()
возвращает индексы отфильтрованных строк в виде a list
.
С помощью этого списка вы можете затем сделать то, что предложил @drew_wood, и перебирать строки, применяя формат к каждой из них таким образом.
for row in rows_with_total: worksheet.set_row(row, None, comma_format)
Полный код
rows_with_total = df[df.applymap(lambda x: True if isinstance(x, str) and 'total' in x.lower() else False).any(1)].index.to_list() for row in rows_with_total: worksheet.set_row(row, None, comma_format)
Ответ №2:
Вы можете сохранить каждую строку в своем фрейме данных в виде списка, используя df.values
Затем вы можете просмотреть этот список, проверив, чтобы увидеть if 'Total' in list:
Если это так, вы можете затем просмотреть каждый столбец в этой строке и присвоить (row_ind,col_ind)
желаемый формат.