Arrays 我怎样才能消除那些等于if条件的行

Arrays 我怎样才能消除那些等于if条件的行,arrays,multidimensional-array,julia,Arrays,Multidimensional Array,Julia,如何从数组中消除与if条件相等的行,该数组称为“情境”您不能只删除Julia中的一行,唯一的方法是创建一个数组副本,而不删除要删除的行。我认为这不是内部实现的,而是有意的 因此,您必须手动执行此操作,类似这样的操作将创建一个不带行i的sition副本(这与说它将删除行i不同) 此外,这实际上会在每次迭代中改变情况的维度,所以要小心 Also2,您的循环将在边界错误中结束,因为最终它将是数组的禁区,也许您可以编写类似这样的内容来结束循环 situation = vcat(situation[1:i

如何从数组中消除与if条件相等的行,该数组称为“情境”

您不能只删除Julia中的一行,唯一的方法是创建一个数组副本,而不删除要删除的行。我认为这不是内部实现的,而是有意的

因此,您必须手动执行此操作,类似这样的操作将创建一个不带行
i
sition
副本(这与说它将删除行
i
不同)

此外,这实际上会在每次迭代中改变
情况的维度,所以要小心

Also2,您的循环将在边界错误中结束,因为最终它将是数组的禁区,也许您可以编写类似这样的内容来结束循环

situation = vcat(situation[1:i-1,:],situation[i+1:end,:])
最终,您可以创建一个函数
delrow
,并从循环中调用它:

if i = length(situation)
    break
else
   i += 1
end

然后调用
situation=delrow(situation,i)

第一件事:问题中的代码没有运行(有几个原因)。在问题中发布代码时,最好将其放在“工作示例”表单中,用户可以将其复制并粘贴到自己选择的编辑器中,这样用户就不必对您实际尝试的操作进行有根据的猜测。这可能是该问题获得否决票的原因之一

有了这一点,就有两种方法可以完成您想要做的事情:

1) 在第一步中构建矩阵,但不包含指定的行。这样以后就不必担心“删除行”。对于问题中这样简单的情况,您可以这样做:

function delrow(array,row)
    return vcat(array[1:row-1,:],array[row+1:end,:])
end
function prealloc1()
    x = zeros(Int64,3^5,5)
    i = 1
    for north=0:2, south=0:2, east=0:2, west=0:2, current=0:2
        x[i,:]=[north, south, east, west, current]
        i += 1
    end
    return(x)
end
注意,我使用的是
Int
,而不是
Int64
。这不会影响性能,这意味着您的代码将同时在32位和64位体系结构上运行

另一个风格提示。不要使用分号来结束行。这是Matlab的一个怪癖,在Julia中不需要它

2) 正如其他用户所建议的那样,您可以构建整个矩阵(包括不需要的行),然后在以后删除它们。当然,这需要重新分配整个矩阵,因此效率较低(注意,您可以就地删除向量元素,即不重新分配,但不能删除维度2或更高的任何数组)。在这种情况下,为了鼓励代码重用,有必要将例程分解为三个单独的函数。首先,我们分配整个矩阵:

function prealloc()
    x = zeros(Int, 3^5 - 3, 5)
    i = 1
    for n=0:2, s=0:2, ea=0:2, w=0:2, cur=0:2
        if !([n, s, ea, w, cur] == [2, 2, 2, 2, 2] || [n, s, ea, w, cur] == [2, 2, 2, 2, 1] || [n, s, ea, w, cur] == [2, 2, 2, 2, 0])
            x[i, :] = [n, s, ea, w, cur]
            i += 1
        end
    end
    return(x)
end
接下来,我们将获得一个要删除的索引向量。我们这样做是因为我们只想重新分配矩阵一次,而不是在每次找到要删除的新行时重新分配。对于您的情况,您可以使用如下函数:

function delrow(array,row)
    return vcat(array[1:row-1,:],array[row+1:end,:])
end
function prealloc1()
    x = zeros(Int64,3^5,5)
    i = 1
    for north=0:2, south=0:2, east=0:2, west=0:2, current=0:2
        x[i,:]=[north, south, east, west, current]
        i += 1
    end
    return(x)
end
请注意,在这个函数的比较语句中,我使用了
[2]
而不是
[2,2,2,2]
。这是因为第一个构造是二维数组(类型
矩阵
),而第二个构造是一维数组(类型
向量
)。由于
x[i,:]
属于
Matrix
类型,因此差异很重要

最后,我们需要重新分配矩阵,而不需要有冲突的行。正如user@Matt B.所建议的,这可以通过以下一个线性函数完成:

function findCondition(x::Matrix{Int})
    inds = Array(Int, 0)
    for i = 1:size(x, 1)
        if x[i, :] == [2 2 2 2 2]
            push!(inds, i)
        elseif  x[i, :] == [2 2 2 2 1]
            push!(inds, i)
        elseif x[i, :] == [2 2 2 2 0]
            push!(inds, i)
        end
    end
    return(inds)
end

请注意,将
setdiff
应用到
IntSet
此处速度很快,因为按构造
inds
已按升序排序。

不支持行删除的原因是,按照您建议的方式执行该操作容易出错(即越界错误)且效率低下。收集要删除的行索引列表,并在最后一次将它们全部删除要好得多:
返回情况[setdiff(1:end,idxs_to_delete),:]
当我执行上面的函数时,我发现错误“冒号没有匹配冒号的方法(::int64,::Array{int64,1})@Taghredmohamed请参阅我的答案,以更全面地解释Matt B.的建议。使用
IntSet
进行索引和setdiff操作可能同样有效(而且更简单)Colin T Bowers,非常感谢你……我会尽力听从你的建议:)@MattB.Yep,做了一个快速的速度测试,
IntSet
结合
setdiff
比我的自定义算法要快。我已经为
union
intersect编写了类似的自定义算法e> 用于任何类型的预排序向量的“小于”的操作“功能已实现。在
Base
中是否已有针对这种情况的方法?我查看了type
Set
,但没有找到太多文档。。。如果答案很长,让我知道,我会把它变成一个新的SO问题。干杯。@ColinTBowers-
Set
确实定义了这些操作,但它是未排序的,所以您所说的优化不适用。有人说要在Base中添加一个
SortedVector
类型,这将透明地允许进行此类优化。或者,如果默认情况下,
Dict
变为有序,则
Set
也会被排序()。作为对答案的另一种优化,您可以将
inds
直接推送到一个整数集中。