I am trying to iterate over two 2D arrays. But, somehow iterator skips every alternate element in row. 'bimg' and 'dist'size is 20x12. But, for every row, it iterates over 0, 2, 4 ... columns instead of 0,1,2,3,4, ...
Code snippet:
it = np.nditer([bimg, dist],
op_flags=[['readonly'],['readonly']],
flags = ['multi_index', 'multi_index'])
rows, cols = bimg.shape
print "bimg dimensions: ", bimg.shape
print "dist dimensions: ", dist.shape
for cur_b, cur_d in it:
print "MULTI_IDX = ", it.multi_index
Output:
bimg dimensions: (20L, 12L)
dist dimensions: (20L, 12L)
MULTI_IDX = (0, 0)
MULTI_IDX = (0, 2)
MULTI_IDX = (0, 4)
MULTI_IDX = (0, 6)
MULTI_IDX = (0, 8)
MULTI_IDX = (0, 10)
MULTI_IDX = (1, 0)
MULTI_IDX = (1, 2)
To understand this issue, if I create array on python prompt and try to iterate over it works correctly:
Correctly working code:
x = np.array(np.arange(240))
x = x.reshape(20,12)
y = np.array(np.arange(240))
y = y + 100
y = y.reshape(20,12)
it = np.nditer([x,y],
op_flags = [['readonly'],['readonly']],
flags= ['multi_index', 'multi_index'])
for a, b in it:
print it.multi_index
Output:
MULTI_INDEX = (0, 0)
MULTI_INDEX = (0, 1)
MULTI_INDEX = (0, 2)
MULTI_INDEX = (0, 3)
MULTI_INDEX = (0, 4)
MULTI_INDEX = (0, 5)
I don't see the difference. When I define:
bimg = x
dist = y
I get the same iteration with both clips.
flags only needs 'multi_index' once. It applies to the whole iteration, op_flags to each array:
flags= ['multi_index']
While the documentation describes nditer as efficient multi-dimensional iterator object, it doesn't seem to help much with speed in Python code. In C or Cython is streamlines the whole process of iterating over multiple array.
Here's another way of generating the multi_index. Actually it's not so different. Internally ndindex constructs a dummy array of the desired shape, and returns an iterable. Look at its code.
for i, j in np.ndindex(bimg.shape):
print i,j
According the tutorial Iterating over Array page, the correct way to use multi_index is with the c style iterator:
while not it.finished:
print it.multi_index
it.iternext()
I'm not sure why. What are the dtypes of bimg and dist?
Related
from numpy import*
def row():
for i in range(len(a)):
for j in range(len(a[i])):
t = [i, j]
inp(*t)
def inp(*m):
a[m] = int(input(f"entert the element of {m} = "))
out(*m)
def out(*o):
print(a[o])
a = zeros((1,2), dtype = int)
row()
Output is showing like this:
enter the element of (0, 0) = 2
2
enter the element of (0, 1) = 3
3
but I want to show output like this
input at a time like this
enter the element of (0, 0) = 2
enter the element of (0, 1) = 3
output at a time like this
2
3
it is possible to do by creating two separate for loop or two function for input and output
but my question is: how can i do it only creating one function
def row():
for i in range(len(a)):
for j in range(len(a[i])):
t = [i, j]
inp(*t)
Instead of printing the output right away, save the values and print them after you've finished collecting them:
import numpy as np
def row(a):
values = []
for i in range(len(a)):
for j in range(len(a[i])):
value = get_input(a, i, j)
values.append(value)
for value in values:
print(value)
def get_input(a, *m):
a[m] = int(input(f"enter the element of {m} = "))
return a[m]
a = np.zeros((1,2), dtype = int)
row(a)
gives
enter the element of (0, 0) = 1
enter the element of (0, 1) = 2
1
2
However, there's an even simpler way: since you also set the new elements in your matrix, you don't have to save them separately but can simply print out the matrix values:
for item in a.ravel():
print(item)
This question already has answers here:
Combinations from range of values for given sizes
(3 answers)
Closed 3 years ago.
I would like to effectively generate a numpy array of tuples which size is the multiple of the dimensions of each axis using numpy.arange() and exclusively using numpy functions. For example: the size of a_list below is max_i*max_j*max_k.
Moreover, the array that I would like to obtain for the example below looks like this : [(0,0,0), (0,0,1), ..., (0, 0, 9), (0, 1, 0), (0, 1, 1), ..., (9, 4, 14)]
a_list = list()
max_i = 10
max_j = 5
max_k = 15
for i in range(0, max_i):
for j in range(0, max_j):
for k in range(0, max_k):
a_list.append((i, j, k))
The loop's complexity above, relying on list and for loops, is O(max_i*max_j*max_k), I would like to use a factorized way to generate a lookalike array of tuples in numpy. Is it possible ?
I like Divakar's solution in the comments better, but here's another.
What you're describing is a cartesian product. With some help from this post, you can achieve this as follows
import numpy as np
# Input
max_i, max_j, max_k = (10, 5, 15)
# Build sequence arrays 0, 1, ... N
arr_i = np.arange(0, max_i)
arr_j = np.arange(0, max_j)
arr_k = np.arange(0, max_k)
# Build cartesian product of sequence arrays
grid = np.meshgrid(arr_i, arr_j, arr_k)
cartprod = np.stack(grid, axis=-1).reshape(-1, 3)
# Convert to list of tuples
result = list(map(tuple, cartprod))
How do I get an array of array with elements like this? Is there an inbuilt scala api that can provide this value (without using combinations)?
e.g
val inp = Array(1,2,3,4)
Output
Vector(
Vector((1,2), (1,3), (1,4)),
Vector((2,3), (2,4)),
Vector((3,4))
)
My answer is below. I feel that there should be an elegant answer than this in scala.
val inp = Array(1,2,3,4)
val mp = (0 until inp.length - 1).map( x => {
(x + 1 until inp.length).map( y => {
(inp(x),inp(y))
})
})
print(mp)
+Edit
Added combination constraint.
Using combinations(2) and groupBy() on the first element (0) of each combination will give you the values and structure you want. Getting the result as a Vector[Vector]] will require some conversion using toVector
scala> inp.combinations(2).toList.groupBy(a => a(0)).values
res11: Iterable[List[Array[Int]]] = MapLike.DefaultValuesIterable
(
List(Array(2, 3), Array(2, 4)),
List(Array(1, 2), Array(1, 3), Array(1, 4)),
List(Array(3, 4))
)
ORIGINAL ANSWER
Note This answer is OK only if the elements in the Seq are unique and sorted (according to <). See edit for the more general case.
With
val v = a.toVector
and by foregoing combinations, I can choose tuples instead and not have to cast at the end
for (i <- v.init) yield { for (j <- v if i < j) yield (i, j) }
or
v.init.map(i => v.filter(i < _).map((i, _)))
Not sure if there's a performance hit for using init on vector
EDIT
For non-unique elements, we can use the indices
val v = a.toVector.zipWithIndex
for ((i, idx) <- v.init) yield { for ((j, jdx) <- v if idx < jdx) yield (i, j) }
I have two arrays of strings, say
A = ('abc', 'joia', 'abas8', '09ma09', 'oiam0')
and
B = ('gfdg', '89jkjj', '09ma09', 'asda', '45645ghf', 'dgfdg', 'yui345gd', '6456ds', '456dfs3', 'abas8', 'sfgds').
What I want to do is simply to count the number of elements of every string in A that appears in B (if any). For example, the resulted array here should be: C = (0, 0, 1, 1, 0). How can I do that?
try this:
A.map( x => B.count(y => y == x)))
You can do it how idursun suggested, it will work, but may be not efficient as if you'll prepare intersection first. If B is much bigger than A it will give massive speedup. 'intersect' method has better 'big-O' complexity then doing linear search for each element of A in B.
val A = Array("abc", "joia", "abas8", "09ma09", "oiam0")
val B = Array("gfdg", "89jkjj", "09ma09", "asda", "45645ghf", "dgfdg", "yui345gd", "6456ds", "456dfs3", "abas8", "sfgds")
val intersectCounts: Map[String, Int] =
A.intersect(B).map(s => s -> B.count(_ == s)).toMap
val count = A.map(intersectCounts.getOrElse(_, 0))
println(count.toSeq)
Result
(0, 0, 1, 1, 0)
Use a foldLeft construction as the yield off of each element of A:
val A = List("a","b")
val B = List("b","b")
val C = for (a <- A)
yield B.foldLeft(0) { case (totalc : Int, w : String) =>
totalc + (if (w == a) 1 else 0)
}
And the result:
C: List[Int] = List(0, 2)
is there any algorithm or method of generating the adjacency matrix for a hypercube for any dimension? say your input is 5 it would create a 5-dimensional hypercube
all i can find are sources from
wiki
and
wolfram
If you want to generate the vertices of a N-D unit hypercube, you can basically make an N-value truthtable. Here's some code I use for that:
function output = ttable(values)
output = feval(#(y)feval(#(x)mod(ceil(repmat((1:x(1))', 1, numel(x) - 1) ./ repmat(x(2:end), x(1), 1)) - 1, repmat(fliplr(y), x(1), 1)) + 1, fliplr([1 cumprod(y)])), fliplr(values));
end
and to get the vertices of a 5-D hypercube you can call it like this:
vertices = ttable(ones(1, 5) * 2) - 1;
From here you can calculate the adjacency matrix by finding all vertices that differ by only one bit, i.e.:
adj_list = zeros(2^5, 5);
adj_mat = zeros(2^5, 2^5);
for v=1:2^5
L1_dists = sum(abs(vertices - repmat(vertices(v, :), 2^5, 1)), 2);
adj_list(v, :) = find(L1_dists == 1);
adj_mat(v, find(L1_dists == 1)) = 1;
end