Оптимизация IF по нескольким критериям - PullRequest
1 голос
/ 30 октября 2010

Я выполняю вычисления в массиве, выполнение которых занимает много времени. Я хотел бы оптимизировать свои формулы еще немного. Все формулы имеют одинаковую природу - они выполняют некоторую высокоуровневую функцию (Среднее, Наклон, Мин, Макс) для столбца значений. Однако не все ячейки в столбце включены в массив. Я использую несколько критериев IF, чтобы выбрать, какие клетки будут включены. Все сравнения сделаны с текущей строкой. Вот пример данных:

     A             B                C            D          E
1    Company       Generation       Date         Value      ToCalculate
2    Abc           1                1/1/2010     5.6          
3    ...           ...              ...          ...        ...

E будет выглядеть примерно так

{=Average(If(A2=A2:A1000, If(B2=B2:B1000, If(C2 > C2:C1000, D2:D1000))))}

Таким образом, после вычисления E2 необходимо заполнить столбец E. В столбце F, G, H, ... используется тот же подход, либо выбираются разные значения для работы или другая функция для выполнения. Мой набор данных довольно большой, и только с несколькими из них на вычисление уходит более часа. Время от времени я добавляю четвертый критерий, все остальные критерии совпадают.

Есть ли эффективность? Некоторые мысли:

  1. Можно ли использовать один массив на столбец вместо тысяч на столбец?
  2. Можно ли сжать первые три критерия, чтобы на выходе были номера строк? Возможно, тогда последующим формулам не придется искать несколько критериев, а можно будет просто выполнить функцию?
  3. или как-то построить критерии? Таким образом, новый столбец возвращает все строки, где компания одинакова. другой столбец возвращает все строки из первого столбца, где генерация одинакова ... и т. д. ...

Ответы [ 2 ]

1 голос
/ 31 октября 2010

Для захвата строк и повторного использования попробуйте этот подход:Сортировать данные по компании и генерации.Составьте уникальный список компаний и поколений (используйте Advanced Filter, Unique Only, Copy)Для каждой пары поколения компании в списке построить 2 столбца формул.В первом столбце указано количество строк в данных для этой пары (используйте COUNTIFS), во втором столбце отображается первая строка в данных для этой пары (= первая строка для предыдущей пары + количество строк для предыдущей пары).Затем вы можете использовать такую ​​функцию, как OFFSET, чтобы возвращать только строки данных для пары Company-Generation и встраивать ее в окончательную формулу функции / массива (AVERAGEIFS и т. Д.)Вы можете расширить этот метод сортировки и подсчета, чтобы включить даты, если хотите.Недостатком является то, что при изменении списка городов и поколений необходимо изменить список уникальных и связанных с ними формул.Есть примеры такого подхода на моем сайте по адресуhttp://www.decisionmodels.com/optspeedk.htm
http://www.decisionmodels.com/optspeedj.htm

1 голос
/ 30 октября 2010

Для среднего вы можете обойтись без массивов:

 =AVERAGEIFS(D2:D$1000,A2:A$1000,A2,B2:B$1000,B2,C2:C$1000,"<="&C2)  

Поскольку есть также COUNTIFS и SUMIFS, я думаю, что ваши наклоны могут быть рассчитаны одинаково.

Для остальных функций (макс., Мин. И т. Д.) Мы должны анализировать каждый случай отдельно.

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

НТН!

Примечание: Excel 2007 и выше!

Редактировать - Ответ на ваш комментарий.

Не зная масштабов проблемы, трудно дать совет, но я все равно рискну:

Вы можете написать функцию VBA, которая:

1) Создает новый лист для каждой пары поколения компании
2) Сортирует данные в этих листах по дате
3) Добавляет формулы к этим листам (в этом контексте никаких условий не требуется)
4) Пересчитывает и получает результаты из этих формул и заполняет исходный лист
5) Удаляет вспомогательные листы

...