降低这个公式的复杂性?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了降低这个公式的复杂性?相关的知识,希望对你有一定的参考价值。
我有一个关于优化我在Google表格中使用的公式的问题:
=ARRAYFORMULA(
IF(
IFERROR(
MATCH($B2 & A2, ($B$1:B1) & ($A$1:A2), 0),
0
) = 0,
1,
0))
该公式通过计算列A(ID)中的所有唯一值来计算,因为它出现在列B(日期)的日期范围内,以在列C(计数)中给出输出。
注意计数值是如何仅为0和1,并且如果它是ID在日期范围中的第一次出现,则仅显示1。
以下示例数据。
ID Date Count
138 Oct-13 1
138 Oct-13 0
29 Oct-13 1
29 Nov-13 1
138 Nov-13 1
138 Nov-13 0
问题是,一旦我获得超过10000行进行解析,该公式就会慢慢地进行计算,并且需要花费一个多小时来完成计算。我想知道是否有人建议如何优化这个公式,所以我不需要让它运行这么长时间。
谢谢,
我一直在玩一些公式,我认为这个更好,但在10000行之后仍然变得非常慢。
=IF(COUNTIF((FILTER($A$1:$A2, $B$1:$B2 = $B2)),$A2) = 1, 1, 0)
编辑
以下是Google产品论坛上发布的附加公式,只需将其放入一个单元格中,然后自动填充。这是我到目前为止找到的最佳答案。
=ArrayFormula(IF(LEN(A2:A),--(MATCH(A2:A&B2:B,A2:A&B2:B,0)=ROW(A2:A)-1),))
我无法找到一个只有公式的解决方案,我可以说它胜过你所拥有的。但是,我确实提出了一个在线性时间内运行的自定义函数,所以它应该表现良好。我很想知道它与你的最终解决方案相比如何。
/**
* Returns 1 for rows in the given range that have not yet occurred in the range,
* or 0 otherwise.
*
* @param {A2:B8} range A range of cells
* @param {2} key_col Relative position of a column to key by, e.g. the sort
* column (optional; may improve performance)
* @return 1 if the values in the row have not yet occurred in the range;
* otherwise 0.
* @customfunction
*/
function COUNT_FIRST_OF_GROUP(range, key_col) {
if (!Array.isArray(range)) {
return 1;
}
const grouped = {};
key_col = typeof key_col === 'undefined' ? 0 : key_col - 1; // convert from 1-based to 0-based
return range.map(function(rowCells) {
const group = groupFor_(grouped, rowCells, key_col);
const rowStr = JSON.stringify(rowCells); // a bit of a hack to identify unique rows, but probably a good compromise
if (rowStr in group) {
return 0;
} else {
group[rowStr] = true;
return 1;
}
});
}
/** @private */
function groupFor_(grouped, row, key_col) {
if (key_col < 0) {
return grouped; // no key column; use one big group for all rows
}
const key = JSON.stringify(row[key_col]);
if (!(key in grouped)) {
grouped[key] = {};
}
return grouped[key];
}
要使用它,请在Google表格中转到工具>脚本编辑器...,将其粘贴到编辑器中,然后点击保存。然后,在电子表格中,使用如下函数:
=COUNT_FIRST_OF_GROUP(A2:B99, 2)
它将自动填充范围内的所有行。你可以see it in action here。
如果满足某些假设,比如,1。相同的ID号总是一起出现(如果没有,也许你可以先按ID排序,然后再排除日期),然后,
=ARRAYFORMULA(1*(A2:A10000&B2:B10000<>A1:A9999&B1:B9999))
如果日期被识别,我认为你可以使用+
而不是&
。同样,在这里和那里做出了各种假设。
以上是关于降低这个公式的复杂性?的主要内容,如果未能解决你的问题,请参考以下文章