代码之家  ›  专栏  ›  技术社区  ›  Marcelo Villa-Piñeros

最像蟒蛇的分裂方式?

  •  1
  • Marcelo Villa-Piñeros  · 技术社区  · 5 年前

    我正在尝试重新分类一个数组,该数组的值从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)
                                                        )))))
    
    1 回复  |  直到 5 年前
        1
  •  4
  •   Jab    5 年前

    你可以分开做。这是更可读的,因为你可以循序渐进。

    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
    
        2
  •  1
  •   r.ook jpp    5 年前

    可能没什么可读性,但你可以试试 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)
            )