大多数pythonic分裂这条线的方式?

问题描述 投票:1回答:2

我试图重新分类一个值为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)
                                                    )))))
python numpy pep8 pep
2个回答
4
投票

你可以单独完成它们。这可以更加可读,因为您可以按照步骤进行操作。

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
投票

可能不是更具可读性,但你可以尝试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)
        )
© www.soinside.com 2019 - 2024. All rights reserved.