Я нашел почти удовлетворительный ответ сам: (минусы: слишком сложно). Например, в R я использовал бы матрицу RowSums
для is.na(df)
. Это так, но, к сожалению, больше кодирования.
def count_nulls_rowwise_by_group(tdf, group):
cdf = pd.concat([tdf[group], pd.isnull(tdf).sum(axis=1).rename('nulls')], axis=1)
return cdf.groupby(group).agg({group: 'count', 'nulls': 'sum'}).rename(index=str, columns={group: 'count'})
count_nulls_rowwise_by_group(tdf)
дает:
Out[387]:
count nulls
indicator
A 2 3
B 2 7
C 1 0
Я сделал что-то подобное для быстрой-и-грязной визуализации воксела 3-х полей с OpenGL.
Я запустил с верхнего левого поля и сохранил опустеть/заполнить флаг. Затем я пытался развернуть прямоугольник направо, пока я не поразил поле другим флагом. Я выполнил в том же вниз направление.
Потяните прямоугольник, если это заполнено.
Если существуют поля remaing, recursivly повторяют процедуру всех трех remaing прямоугольников, вызванных последним прямоугольником, которые являются правильными, нижняя часть и нижними правыми:
xxxx 1111
xxxx 1111
xxxx 1111
2222 3333
2222 3333
2222 3333
Взгляните на эту статью от Портала доктора Dobb на нахождении максимального прямоугольника в Вашей ситуации. Это - очень детальное обсуждение чрезвычайно эффективного алгоритма, и я думаю, что повторение его многократно возможно решило бы Вашу проблему.
Таким образом, Вы ищете прямоугольную границу 'НА' квадратах?
Вы хотите внутреннее или связанное внешнее?
т.е. граница должна только иметь 'НА' квадратах, или Вы хотите, чтобы прямоугольник содержал весь 'НА' квадратах в группе?
Поскольку Вы не ищете минимальное количество квадратов, я предложил бы использовать компромисс, который все еще сохраняет Ваш алгоритм простым.
То, что лучшее решение, зависит от Ваших данных, но одна простая альтернатива должна просто собрать поля вдоль одной строки. Т.е.:
0 0 1 1 1 0 0 0 1 1 1 1 0
Приведет к:
skip 2
draw 3
skip 3
draw 4
skip 1
Это сократит количество вызовов для рисования поля без любой потребности кэширования (т.е. можно создать поля на лету).
Если бы Вы хотите создать большие поля, я предложил бы алгоритм отслеживания в обратном порядке там, Вы находите первый 1 и пытаетесь развернуть поле во всех направлениях. Создайте список полей и очиститесь 1:s, поскольку Вы использовали их.