XLSXWriter FILTER (): ссылка на другой лист? - PullRequest
1 голос
/ 03 апреля 2020

У меня есть вкладка под названием Sheet1. Он фильтрует данные из вкладки с именем Data_Summary.

Если я введу эту функцию FILTER () в ячейку A2 Sheet1 и нажму return:

=FILTER(Data_Summary!A20:B91,Data_Summary!B20:B91="Assigned")

... все работает как ожидается:

enter image description here

Но если я введу это через XLSXWriter:

worksheet.write_array_formula("A2:B73", "=_xlfn._xlws.FILTER(Data_Summary!A20:B91,Data_Summary!B20:B91=\"Assigned\")")

... фильтр все еще работает, но в строки, следующие за фильтрованными строками, я получаю много строк, содержащих #N/A.

enter image description here

Как я могу исправить это?

1 Ответ

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

Вы получаете много значений N / A, потому что вы определяете больший массив, чем возвращаемые результаты. В случае, если вы вводите функцию FILTER () вручную, она автоматически заполняется в зависимости от того, сколько результатов она возвращает. Но с xlsxwriter я не смог найти способ написать формулу, кроме как с помощью метода write_array_formula и определения определенного диапазона c. Это не удобно, потому что я предполагаю, что в большинстве случаев вы не знаете, сколько результатов вы получите.

Я нашел решение, посчитав, сколько вхождений строки «Назначено» в вашем диапазоне и затем используйте это число в качестве конечной строки для массива формулы. Но для этого требуется, чтобы вы импортировали ваш фрейм данных через pandas. Насколько я знаю, нет способа прочитать значение ячейки с помощью xlsxwriter и использовать его позже в формуле, возможно, Джон мог бы пролить больше света на это.

Вот рабочий пример, основанный на информации, которую вы предоставил нам:

import pandas as pd
import numpy as np

# Cretae a test df
df = pd.DataFrame({'Track Number': ['Track #1','Track #2','Track #3','Track #4','Track #5',
                                    'Track #6','Track #7','Track #8','Track #9','Track #10'],
                   'Status': ['Assigned',np.nan,'Assigned',np.nan,np.nan,
                              'Assigned','Assigned',np.nan,np.nan,np.nan]})

# Start the xlsxwriter
writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
workbook  = writer.book
worksheet = workbook.add_worksheet()

# You could count them using excel's native formula but you will not be able to store it
# into a variable as the formulas are calculated when the file opens
#worksheet.write_formula('D1', '=COUNTIF(Data_Summary!B:B,"Assigned")')

# Using pandas is possible though
# Use loc or iloc for specific range, otherwise pass in the whole column df['Status']
count = df.loc[0:10,'Status'].str.count('Assigned').sum()
worksheet.write_array_formula(f'A1:B{count}', '=_xlfn._xlws.FILTER(Data_Summary!A1:B11,Data_Summary!B1:B11="Assigned")')

# Pass the main df to a second sheet named Data_Summary
df.to_excel(writer, sheet_name='Data_Summary', index=False)

writer.save()

ВЫХОД :

Main df:

enter image description here

Результат: enter image description here

Если я определю больший диапазон, чем возвращаемые результаты, например:

worksheet.write_array_formula('A1:B8', '=_xlfn._xlws.FILTER(Data_Summary!A1:B11,Data_Summary!B1:B11="Assigned")')

я вернусь # N / As:

enter image description here

...