【问题标题】:Most pythonic way to split this line?分割这条线的最pythonic方式?
【发布时间】:2019-03-06 18:14:43
【问题描述】:

我正在尝试将值从 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)
                                                    )))))

【问题讨论】:

  • con1等是什么?
  • 这似乎是一个代码审查问题:)
  • 使用循环,卢克

标签: python numpy pep8 pep


【解决方案1】:

您可以分别进行所有操作。这更具可读性,因为您可以逐步进行操作。

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

【讨论】:

  • 您甚至可能想使用for 循环覆盖enumerate([con6, con5, ...]) 之类的东西
  • 我会在里面做广告
  • 我认为如果我分开调用我会遇到重叠值的问题,但事实并非如此。循环是个好主意,感谢您的回答!
【解决方案2】:

可能不会更易读,但你可以试试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)
        )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多