The rest of my earlier comment is likely still relevant except that you might need to use eachrow(states[:, 1:3]) instead of eachcol(states[1:3, :]).
In general, the NumPy/MATLAB/etc pattern of smooshing all your data into a mega-array and then slicing-and-dicing it during processing is not necessary in Julia (or other languages where non-arrays are performant). Where relevant, you might consider using types to organize your data a little more carefully. For example:
julia> struct StateDescriptor
state1::NTuple{3, Int} # maybe even make a special type for these
state2::NTuple{3, Int}
freq_diff::Float64
end
julia> bunch_of_states = [StateDescriptor((1,1,0), (1,0,1), 6380.35), StateDescriptor((1,1,1), (1,0,1), 6316.91), StateDescriptor((2,1,1), (2,0,2), 6444.27), StateDescriptor((2,1,2), (1,0,1), 11086.5)]
4-element Vector{StateDescriptor}:
StateDescriptor((1, 1, 0), (1, 0, 1), 6380.35)
StateDescriptor((1, 1, 1), (1, 0, 1), 6316.91)
StateDescriptor((2, 1, 1), (2, 0, 2), 6444.27)
StateDescriptor((2, 1, 2), (1, 0, 1), 11086.5)
julia> all_states = vcat([x.state1 for x in bunch_of_states], [x.state2 for x in bunch_of_states])
8-element Vector{Tuple{Int64, Int64, Int64}}:
(1, 1, 0)
(1, 1, 1)
(2, 1, 1)
(2, 1, 2)
(1, 0, 1)
(1, 0, 1)
(2, 0, 2)
(1, 0, 1)
julia> unique_states = unique(all_states)
6-element Vector{Tuple{Int64, Int64, Int64}}:
(1, 1, 0)
(1, 1, 1)
(2, 1, 1)
(2, 1, 2)
(1, 0, 1)
(2, 0, 2)
julia> findall(isequal(unique_states[1]), x.state1 for x in bunch_of_states) # (1, 1, 0) in state1
1-element Vector{Int64}:
1
julia> findall(isequal(unique_states[5]), x.state2 for x in bunch_of_states) # (1, 0, 1) in state2
3-element Vector{Int64}:
1
2
4
Done this way, there isn’t even a question about rows versus columns. I’m sure you’d want to make some adjustments to what I’ve suggested based on your full use case, but in general I find data/code like this much easier to reason about.