Самый питонический способ разделить эту линию? - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь переклассифицировать массив, который имеет значения от 0 до 15, с новыми значениями от 0 до 5.

У меня следующие условия:

con1 = np.in1d(arr, [0, 11, 13, 15]).reshape((y, x))  # new val 0
con2 = np.in1d(arr, [1, 2, 3, 4, 5]).reshape((y, x))  # new val 1
con3 = (arr == 6) | (arr == 7)                        # new val 2
con4 = (arr == 8) | (arr == 9)                        # new val 3
con5 = (arr == 10)                                    # new val 4
con6 = (arr == 12) | (arr == 14)                      # new val 5

У меня есть следующеестрока в python

return np.where(con1, 0, np.where(con2, 1, np.where(con3, 2, np.where(con4, 3, np.where(con5, 4, np.where(con6, 5, arr))))))

длиной 128 символов (включая отступ внутри функции).PEP8 предполагает, что строки не должны превышать 79 символов.Однако я не уверен, что является лучшим способом разбить эту строку на несколько строк, сохраняя читабельность.

Я пробовал два варианта, но они кажутся трудными для чтения.

Вариант 1:

return np.where(con1, 0, np.where(
    con2, 1, np.where(
        con3, 2, np.where(
            con4, 3, np.where(
                con5, 4, np.where(
                    con6, 5, arr))))))

Вариант 2:

return np.where(con1, 0, 
                np.where(con2, 1, 
                         np.where(con3, 2, 
                                  np.where(con4, 3, 
                                           np.where(con5, 4, 
                                                    np.where(con6, 5, arr)
                                                    )))))

Ответы [ 2 ]

4 голосов
/ 06 марта 2019

Вы могли бы сделать их все по отдельности.Это более читабельно, так как вы можете следовать шаг за шагом.

filtered_result = np.where(con6, 5, arr)
filtered_result = np.where(con5, 4, filtered_result)
filtered_result = np.where(con4, 3, filtered_result)
filtered_result = np.where(con3, 2, filtered_result)
filtered_result = np.where(con2, 1, filtered_result)
filtered_result = np.where(con1, 0, filtered_result)

return filtered_result

Чтобы придерживаться pep8, о чем вы и просите, тогда это путь

Редактирование

цикл for также значительно уменьшит повторяемость и все еще будет читабельным.

connections = iter((con6, con5, con4, con3, co2, con1, con0))
filters = range(len(connections)-2, 0 -1)

filtered_result = np.where(next(connections), next(filters), arr)

for n, con, in zip(filters, connections):
    filtered_result = np.where(con, n, filtered_result)

return filtered_result
1 голос
/ 06 марта 2019

Может быть не так много читабельнее, но вы можете попробовать reduce:

from functools import reduce

def some_func():

    ... some code maybe ...

    args = [con1, con2, con3, con4, con5, con6]
    return reduce(
            lambda prev_arg, new_arg: np.where(*new_arg, prev_arg), 
            enumerate(args[:-1]), 
            np.where(args[-1], len(args)-1, arr)
        )
...