【问题标题】:Numpy vstack if not emptyNumpy vstack 如果不为空
【发布时间】:2021-11-04 06:14:15
【问题描述】:

我需要垂直堆叠 numpy 数组,这是来自function_returns_some_np_array 的返回值。该函数总是返回一个相同形状的数组。在这种情况下长度为 10。如果我不检查 X 是否不为空,则会出现以下错误。

ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 0 and the array at index 1 has size 10

包含校验的代码:

    X = np.empty(0)
    if X.size == 0:
         X = function_returns_some_np_array(data)
    else:
         X = np.vstack((X, function_returns_some_np_array(data)))

是否总是需要检查数组是否不为空,或者是否有单行解决方案来处理这个问题?内置的东西会很棒。所以总结一下这个问题。此操作是否有更短的解决方案?

谢谢

【问题讨论】:

    标签: python arrays numpy stack


    【解决方案1】:

    您的示例缺少一些上下文,X 的迭代堆叠表明它发生在某种循环中?

    通常最好避免这样的迭代堆叠(或追加等),因为它会强制 Numpy 每次都创建一个新数组。

    如果您的用例类似于:

    func = lambda x: np.random.randn(x)
    data = 10000
    
    X = None
    
    for _ in range(50):
    
        if X is None:
             X = func(data)
        else:
             X = np.vstack((X, func(data)))
    

    我会简单地将中间结果收集到一个列表中,最后只堆叠一次。但这假设您在计算中不需要那个中间堆栈。如果这样做,最初预分配“最终”数组并插入函数的结果可能会有所帮助,但这需要知道最终大小(n 次迭代/调用)。

    例如:

    res = []
    for _ in range(50):
        res.append(function_returns_some_np_array(data))
    
    X = np.vstack(res)    
    

    这删除了 ​​if 语句,使其更易于阅读,您在开始时只有一个初始化“问题”,而不是一个真正的决定,需要 if 语句。 p>

    与顶部相比,它也快了大约 3 倍,但这实际上取决于返回数组的大小与迭代次数。

    【讨论】:

    • 感谢您的回答。数据在 for 循环中。你从哪里知道哪一个快多少?它的安静是一个有趣的见解
    • 这是基于我使用上述代码和timeit 模块所做的简单基准测试。但是你问题的那一部分是编程中一个非常基本的问题,并且已经专门针对 Python\Numpy 进行了很多讨论。例如:stackoverflow.com/a/46103554/1755432
    猜你喜欢
    • 2015-02-02
    • 2019-08-24
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2021-12-29
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多