что означает 1 в массиве [] в Джулии?

Я нахожусь в ситуации, когда мне нужно переписать некоторый код Julia в код Python, и я не могу воспроизвести эту строку.

if 1 in array1[array2] || 1 in array1[array3]

Насколько я понимаю, эта строка сравнивает массивы array1 с array2 и array1 с array3, чтобы увидеть, равен ли индекс array2 из array1 1 или индекс array3 из array1 равен 1.

Итак, я воспроизвел этот код в код Python с моим пониманием,

for i, j in zip(array2, array3):
    if array1[i] == 1 or array1[j] == 1:

Но этот код не работал, как приведенный выше код, и я получил ValueError, как показано ниже:

ValueError: значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any() или a.all()

Я не уверен, что это мое непонимание строки Джулии или мой код Python неверен.

Может ли кто-нибудь сказать мне, что не так?

[править]: Вот код Джулии этой проблемы. здесь я использую сеть клубов карате в качестве входной матрицы dir = to/your/path ln = soc-karate.mtx

mtx = MatrixMarketRead(string(dir,strip(ln)));
A = mtx - spdiagm(diag(mtx))
n = size(A,1);
A = speye(n) - A * spdiagm(1./vec(sum(A,1)));
println(A)
function findDegrees(Ac::SparseMatrixCSC)
  degrees = zeros(Int,length(Ac.colptr)-1)
    for i = 1:length(degrees)
      degrees[i] = Ac.colptr[i+1]-Ac.colptr[i]-1
    end
  return degrees
end

function lowDegreeNodes(A::SparseMatrixCSC,At::SparseMatrixCSC,d::Int64,dout::Vector,din::Vector)
  # 1: find low degree nodes
  n = size(A,1)
  U = collect(dout.==1)
  println(U)
  V = collect(din.==1)
  Z = min((dout+din) .>= 1 , (dout+din) .<= 8 )
  # 2:  visited = 0  ==> NotVisited
  #             = 1  ==> FNode
  #             = 2  ==> NotEliminated
  visited = zeros(length(U))
  
  for u = 1:n
    if Z[u]
      if visited[u] == 0
        Au = A.rowval[ A.colptr[u]:A.colptr[u+1]-1 ]
        Av = At.rowval[ At.colptr[u]:At.colptr[u+1]-1 ]
        if 1 in visited[Au] || 1 in visited[Av]
          visited[u] = 2
        else
          visited[Au] = 2
          visited[u] = 1
        end
      end
    end

    if V[u]
      if visited[u] == 0
        Au = A.rowval[ A.colptr[u]:A.colptr[u+1]-1 ]
        Av = At.rowval[ At.colptr[u]:At.colptr[u+1]-1 ]
        if 1 in visited[Au] || 1 in visited[Av]
          visited[u] = 2
        else
          visited[Av] = 2
          visited[u] = 1
        end
      end
    end

    if U[u]
      if visited[u] == 0
                Au = A.rowval[ A.colptr[u]:A.colptr[u+1]-1 ]

        Av = At.rowval[ At.colptr[u]:At.colptr[u+1]-1 ]
        if 1 in visited[Au] || 1 in visited[Av]
          visited[u] = 2
        else
          visited[Av] = 2
          visited[u] = 1
        end
      end
    end
  end
  return visited .== 1
end
dout = findDegrees(A)
din = findDegrees(A')
z = lowDegreeNodes(A, A', 3, dout, din)

person S.Ky    schedule 06.01.2021    source источник
comment
похоже, что ваши массивы многомерны... пожалуйста, предоставьте минимальный воспроизводимый пример.   -  person Julien    schedule 06.01.2021
comment
Альтернативой преобразованию может быть вызов Julia из Python с помощью pyJulia (или наоборот с помощью PyCall). В целом, Julia — гораздо более производительный язык, поэтому преобразование вашего кода в Python может оказаться невыгодным в долгосрочной перспективе.   -  person lungben    schedule 06.01.2021
comment
@lungben этот код Джулии написан на Джулии 0.5.2. будет нормально работать?   -  person S.Ky    schedule 07.01.2021
comment
Вы должны попробовать это. Джулия 0.5 довольно старая, и до Джулии 1.0 были внесены серьезные изменения.   -  person lungben    schedule 07.01.2021


Ответы (3)


if 1 in array1[array2] || 1 in array1[array3]

Насколько я понимаю, эта строка сравнивает массивы array1 с array2 и array1 с array3, чтобы увидеть, равен ли индекс array2 массива1 1 или индекс array3 массива1 равен 1.

Я не думаю, что это правильно. Я думаю, что эта строка проверяет, находится ли 1 в значениях array1 по индексам array2 или индексам array3. Позвольте мне сделать MWE:

julia> array2 = [2, 3]
2-element Array{Int64,1}:
 2
 3

julia> array3 = [4, 5]
2-element Array{Int64,1}:
 4
 5

julia> array1 = [1, 9, 1, 2, 3]
5-element Array{Int64,1}:
 1
 9
 1
 2
 3

julia> 1 in array1[array2] || 1 in array1[array3]
true

julia> array1 = [1, 9, 4, 2, 3] # now only at the 1st position is there a 1
5-element Array{Int64,1}:
 1
 9
 4
 2
 3

julia> 1 in array1[array2] || 1 in array1[array3]
false
person Benoit Pasquier    schedule 06.01.2021
comment
На самом деле, синтаксис Julia почти такой же, как и в Python, вам просто нужно заменить || по или. - person lungben; 06.01.2021
comment
Python, в отличие от Julia, использует индексирование на основе 0, поэтому, скорее всего, вам нужно будет вычесть 1 из массива2 и массива3. - person Przemyslaw Szufel; 06.01.2021

Вы правильно поняли эту строку:

Редактировать: хорошо, прочитав ваше описание еще раз, я не уверен, что понял правильно, но, надеюсь, это объяснение прояснит его.

if 1 in array1[array2] || 1 in array1[array3]

Вы выбираете элементы в array1 по индексам, заданным array2 и array3, и проверяете, является ли какой-либо из этих элементов 1

Итак, если ваш array1 равен [0, 1, 2, 3, 4, 5, 6], а array2 равен [1, 3, 4], array1[array2] будет [0, 2, 3] (помните, массивы индексируются 1 в Джулии!) и, таким образом, 1 in array1[array2] будет равно false.

Вы можете добиться чего-то подобного с numpy, но помните, что, поскольку индексы python равны 0, вам нужно вычесть 1 из индексов, если вы хотите, чтобы код оставался эквивалентным для тех же входных данных:

array1 = np.array([...]) # Fill your arrays with the data
array2 = np.array([...])
array3 = np.array([...])


if 1 in array1[array2 - 1] or 1 in array1[array3 - 1]:
    # Rest of code

Синтаксис 1 in <array> такой же, как и в Julia, он оценивается как True, если значение 1 содержится в <array>.

person mandulaj    schedule 06.01.2021

Если это обычные списки Python (и построенные с учетом 0 индексированных массивов), вы можете сделать

array1 = [1,1,2,2,3,3]
array2 = [0,2]
array3 = [3,5]

print(any(array1[i]==1 for i in array2), any(array1[i]==1 for i in array3))

if any(array1[i]==1 for i in array2) or any(array1[i]==1 for i in array3):
    print("Yes")

Это не удастся, если индексы во вторых двух массивах переполнят первый. В этом случае вы можете сначала почистить их.

array2 = [i for i in array2 if i < len(array1)]
array3 = [i for i in array3 if i < len(array1)]
person tdelaney    schedule 06.01.2021
comment
Я запустил print(any(array1[i] == 1 for I in array2)) и получил ошибку TypeError: only integer scalar arrays can be converted to a scalar index несмотря на то, что array2 содержит элементы int. array2 есть [array([ 7, 12], dtype=int32)] для вашего сведения. - person S.Ky; 06.01.2021
comment
Я показываю, как это будет работать со списками. Этот точный код работает для вас? Вы не сказали нам, какие типы этих массивов. Можете ли вы опубликовать полностью работающий пример? Модули расширения Python, такие как numpy и pandas, будут работать иначе, чем ванильный список целых чисел. Я показал вам, как это сделать с этими основными типами. - person tdelaney; 06.01.2021