Related
Say I had a list:
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
Would there be any way too take out the first 4 values of the list, make them :
[4, 2, 2, 4]
and the put them back in the list so the list now looks like
[4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
and do all of this without making the list
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
at the start.
Also if possible, can you make a loop to do this for all the 4 values available.
So that the list now looks like:
[4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
fill = [4, 2, 2, 4]
for i in range(0, len(lis), len(fill)):
lis[i : i + len(fill)] = fill
print(lis)
This outputs:
[4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
Just do like this:
lis1 = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
# change first 4 index
lis1[:4] = 4,2,2,4
print(lis1)
# [4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
lis2 = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
# change every 4 index in loop
for i in range(0,len(lis2),4):
lis2[i:i+4] = 4,2,2,4
print(lis2)
# [4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
Use itertools.cycle and itertools.islice:
from itertools import cycle, islice
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
out = list(map(int, islice(cycle('4224'), len(lis))))
print(out)
# [4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
Or a simpler way (without any imports):
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
out = list(map(int, '4224' * (len(lis) // 4)))
print(out)
# [4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
def list_function(original_list, list_of_value_to_subst):
original_list[:len(list_of_value_to_subst)]=list_of_value_to_subst
print (original_list)
subst_list = list(map(int, list_of_value_to_subst * (len(original_list) // len(list_of_value_to_subst))))
print (subst_list)
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
list_of_value_to_subst=[4, 2, 2, 4]
list_function(lis, list_of_value_to_subst)
output:
[4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
Another solution, would be to do the following:
For your first question:
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
ins = [4, 2, 2, 4]
lis[:len(ins)] = ins
print(lis)
Output:
[4, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
For your second question:
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
lis = ins * int(len(lis) / len(ins))
print(lis)
Output:
[4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4]
Given the list of numbers you want to replace the first part of lis with:
replace_lis = [4, 2, 2, 4]
You can iterate over the length of replace_lis, and fill in the index spots in lis accordingly:
for i in range(len(replace_lis)):
if i < len(lis):
lis[i] = replace_lis[i]
The i < len(lis) is if replace_lis could be bigger than lis. If there is no chance of that, you can safely omit that if statement.
Here is your original list:
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
and you'd like to replace the first 4 items with:
[4, 2, 2, 4]
Let's assign the new values a new variable. Let's call it update. So:
update = [4, 2, 2, 4]
Here is your code:
lis = [0, 0, 0, 0, 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0]
update = [4, 2, 2, 4]
for i in range(0, len(update)):
lis[i] = update[i]
print(lis)
Folks this is driving me crazy.
I have the following functions defined below
I get the expected result from maskArray() when I pass it anchor='top' or anchor='left', but it returns and all zeros numpy array in case of 'bottom' and 'right'. I thought i got the slicing wrong, so i experimented with the statements mask[-y:,:] = somevalue outside the function and it works so I believe the syntax is right. Not sure what is going on here.
Here are examples of function calls results
In [5]: x = np.round(np.random.rand(10,10) * 10).astype(np.uint8)
In [6]: x
Out[6]:
array([[ 3, 2, 1, 10, 4, 7, 7, 9, 6, 5],
[ 1, 6, 3, 0, 9, 3, 7, 6, 0, 4],
[ 4, 2, 5, 3, 4, 7, 6, 2, 0, 3],
[ 1, 4, 10, 2, 8, 1, 9, 10, 4, 8],
[ 9, 8, 3, 5, 3, 0, 10, 5, 2, 3],
[ 1, 9, 8, 6, 1, 3, 7, 4, 9, 3],
[ 8, 8, 4, 6, 9, 1, 10, 6, 9, 7],
[ 6, 2, 4, 8, 2, 9, 2, 4, 7, 4],
[ 7, 9, 2, 6, 9, 2, 6, 8, 7, 8],
[ 4, 6, 3, 5, 7, 5, 3, 3, 5, 5]], dtype=uint8)
In [7]: maskArray(x,0.3333,'top')
Out[7]:
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
In [8]: maskArray(x,0.3333,'left')
Out[8]:
array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
In [9]: maskArray(x,0.3333,'bottom')
Out[9]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
Can any of you see something that I'm not seeing ?
My other questions is : is there a way to make the slicing statement generic for any dimension of np.array ? meaning instead of having an if statement for each expected array.ndim (i.e: [:x,:] and [:x,:,:] )
Cheers
import numpy as np
def getChannels(srx):
try:
if srx.ndim == 2:
return 0
elif srx.ndim == 3:
return srx.shape[2]
else:
return None
except TypeError:
print("srx is not a numpy.array")
def maskArray(dsx, fraction, anchor):
if anchor == 'top':
y = np.round(dsx.shape[0] * fraction).astype(np.uint8)
mask = np.zeros_like(dsx)
if getChannels(dsx) == 0:
mask[:y,:] = 1
return mask
elif getChannels(dsx) == 3:
mask[:y,:,:] = 1
return mask
else:
return None
elif anchor == 'bottom':
y = np.round(dsx.shape[0] * fraction).astype(np.uint8)
mask = np.zeros_like(dsx)
if getChannels(dsx) == 0:
mask[-y:,:] = 1
return mask
elif getChannels(dsx) == 3:
mask[-y:,:,:] = 1
return mask
else:
return None
elif anchor == 'left':
x = np.round(dsx.shape[1] * fraction).astype(np.uint8)
mask = np.zeros_like(dsx)
if getChannels(dsx) == 0:
mask[:,:x] = 1
return mask
elif getChannels(dsx) == 3:
mask[:,:x,:] = 1
return mask
else:
return None
elif anchor == 'right':
x = np.round(dsx.shape[1] * fraction).astype(np.uint8)
mask = np.zeros_like(dsx)
if getChannels(dsx) == 0:
mask[:,-x:] = 1
return mask
elif getChannels(dsx) == 3:
mask[:,-x:,:] = 1
return mask
else:
return None
When you ask for the negative of a type uint8 variable, the result overflows, because negative values don't exist for this type:
>>> -np.round(10 * 0.3333).astype('uint8')
253
Use a signed integer type and it will work as expected:
>>> -np.round(10 * 0.3333).astype('int')
-3
I am trying to make a diagonal numpy array from:
[1,2,3,4,5,6,7,8,9]
Expected result:
[[ 0, 0, 1, 0, 0],
[ 0, 0, 0, 2, 0],
[ 0, 0, 0, 0, 3],
[ 4, 0, 0, 0, 0],
[ 0, 5, 0, 0, 0],
[ 0, 0, 6, 0, 0],
[ 0, 0, 0, 7, 0],
[ 0, 0, 0, 0, 8],
[ 9, 0, 0, 0, 0]]
What would be an efficient way of doing this?
You can use integer array indexing to set the specified elements of the output:
>>> import numpy as np
>>> a = [1,2,3,4,5,6,7,8,9]
>>> arr = np.zeros((9, 5), dtype=int) # create empty array
>>> arr[np.arange(9), np.arange(2,11) % 5] = a # insert a
>>> arr
array([[0, 0, 1, 0, 0],
[0, 0, 0, 2, 0],
[0, 0, 0, 0, 3],
[4, 0, 0, 0, 0],
[0, 5, 0, 0, 0],
[0, 0, 6, 0, 0],
[0, 0, 0, 7, 0],
[0, 0, 0, 0, 8],
[9, 0, 0, 0, 0]])
Inspired by np.fill_diagonal which can wrap, but not offset:
In [308]: arr=np.zeros((9,5),int)
In [309]: arr.flat[2:45:6]=np.arange(1,10)
In [310]: arr
Out[310]:
array([[0, 0, 1, 0, 0],
[0, 0, 0, 2, 0],
[0, 0, 0, 0, 3],
[0, 0, 0, 0, 0],
[4, 0, 0, 0, 0],
[0, 5, 0, 0, 0],
[0, 0, 6, 0, 0],
[0, 0, 0, 7, 0],
[0, 0, 0, 0, 8]])
(though for some reason this has the 4th all zero row).
def fill_diagonal(a, val, wrap=False):
...
step = a.shape[1] + 1
# Write the value out into the diagonal.
a.flat[:end:step] = val
HOW TO concate C1 and C2 by different dimension?
C1 =[[0,0,1,0],
[2,0,0,0],
[0,0,0,0]]
C2=[[0,3,4,0,1,1],
[0,0,0,5,1,1],
[6,7,0,8,1,1]]
how to get the following result:
[[0 ,0 ,1 ,0 ,0, 3, 4, 0,1,1]
[2, 0, 0, 0, 0, 0 ,0 ,5,1,1]
[0, 0, 0 ,0 ,6 ,7, 0, 8,1,1]]
and
[[0,0,1,0],
[2,0,0,0],
[0,0,0,0],
[0,3,4,0,1,1],
[0,0,0,5,1,1],
[6,7,0,8,1,1]]
>>> [r1+r2 for (r1, r2) in zip(C1, C2)]
[[0, 0, 1, 0, 0, 3, 4, 0, 1, 1], [2, 0, 0, 0, 0, 0, 0, 5, 1, 1], [0, 0, 0, 0, 6, 7, 0, 8, 1, 1]]
>>> C1 + C2
[[0, 0, 1, 0], [2, 0, 0, 0], [0, 0, 0, 0], [0, 3, 4, 0, 1, 1], [0, 0, 0, 5, 1, 1], [6, 7, 0, 8, 1, 1]]
Using List Comprehensions -
>>> [i[0]+i[1] for i in zip(C1, C2)]
[[0, 0, 1, 0, 0, 3, 4, 0, 1, 1], [2, 0, 0, 0, 0, 0, 0, 5, 1, 1], [0, 0, 0, 0, 6, 7, 0, 8, 1, 1]]
>>> C1 + C2
[[0, 0, 1, 0], [2, 0, 0, 0], [0, 0, 0, 0], [0, 3, 4, 0, 1, 1], [0, 0, 0, 5, 1, 1], [6, 7, 0, 8, 1, 1]]
I have two labelled 2D numpy arrays a and b with identical shapes. I would like to re-label the array b by something similar to a GIS geometric union of the two arrays, such that cells with unique combination of values in array a and b are assigned new unique IDs:
I'm not concerned with the specific numbering of the regions in the output, so long as the values are all unique. I have attached sample arrays and desired outputs below: my real datasets are much larger, with both arrays having integer labels which range from "1" to "200000". So far I've experimented with concatenating the array IDs to form unique combinations of values, but ideally I would like to output a simple set of new IDs in the form of 1, 2, 3..., etc.
import numpy as np
import matplotlib.pyplot as plt
# Example labelled arrays a and b
input_a = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0],
[0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
[0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
input_b = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# Plot inputs
plt.imshow(input_a, cmap="spectral", interpolation='nearest')
plt.imshow(input_b, cmap="spectral", interpolation='nearest')
# Desired output, union of a and b
output = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 2, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 2, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 4, 7, 7, 7, 7, 0, 0],
[0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
[0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
[0, 0, 5, 5, 5, 6, 7, 7, 7, 7, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# Plot desired output
plt.imshow(output, cmap="spectral", interpolation='nearest')
If I understood the circumstances correctly, you are looking to have unique pairings from a and b. So, 1 from a and 1 from b would have one unique tag in the output; 1 from a and 3 from b would have another unique tag in the output. Also looking at the desired output in the question, it seems that there is an additional conditional situation here that if b is zero, the output is to be zero as well irrespective of the unique pairings.
The following implementation tries to solve all of that -
c = a*(b.max()+1) + b
c[b==0] = 0
_,idx = np.unique(c,return_inverse= True)
out = idx.reshape(b.shape)
Sample run -
In [21]: a
Out[21]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0],
[0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0],
[0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
[0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [22]: b
Out[22]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
In [23]: out
Out[23]:
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 3, 5, 5, 5, 5, 0, 0],
[0, 0, 1, 1, 1, 3, 5, 5, 5, 5, 0, 0],
[0, 0, 1, 1, 1, 2, 4, 4, 4, 4, 0, 0],
[0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
[0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
[0, 0, 6, 6, 6, 7, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
Sample plot -
# Plot inputs
plt.figure()
plt.imshow(a, cmap="spectral", interpolation='nearest')
plt.figure()
plt.imshow(b, cmap="spectral", interpolation='nearest')
# Plot output
plt.figure()
plt.imshow(out, cmap="spectral", interpolation='nearest')
Here is a way to do it conceptually in terms of set union, but not to GIS geometric union, since that was mentioned after I answered.
Make a list of all possible unique 2-tuples of values with one from a and the other from b in that order. Map each tuple in that list to its index in it. Create the union array using that map.
For example say a and b are arrays each containing values in range(4) and assume for simplicity they have the same shape. Then:
v = range(4)
from itertools import permutations
p = list(permutations(v,2))
m = {}
for i,x in enumerate(p):
m[x] = i
union = np.empty_like(a)
for i,x in np.ndenumerate(a):
union[i] = m[(x,b[i])]
For demonstration, generating a and b with
np.random.randint(4, size=(3, 3))
produced:
a = array([[3, 0, 3],
[1, 3, 2],
[0, 0, 3]])
b = array([[1, 3, 1],
[0, 0, 1],
[2, 3, 0]])
m = {(0, 1): 0,
(0, 2): 1,
(0, 3): 2,
(1, 0): 3,
(1, 2): 4,
(1, 3): 5,
(2, 0): 6,
(2, 1): 7,
(2, 3): 8,
(3, 0): 9,
(3, 1): 10,
(3, 2): 11}
union = array([[10, 2, 10],
[ 3, 9, 7],
[ 1, 2, 9]])
In this case the property that a union should be bigger or equal to its composits is reflected in increased numerical values rather than increase in number of elements.
An issue with using itertools permutations is that the number of permutations could be much larger than needed. It would be much larger if the number of overlaps per area is much smaller than the number of areas.
The question uses Union but the picture shows an Intersection. Divakar's answer replicates the pictured Intersection, and is more elegant than my solution below, which produces the Union.
One could make a dictionary of only the actual overlaps, and then work from that. Flattening the input arrays first makes this easier for me to see, I'm not sure if that is feasible for you:
shp = numpy.shape(input_a)
a = input_a.flatten()
b = input_b.flatten()
s = set(((i,j) for i,j in zip(a,b))) # unique pairings
d = {p:i for i,p in enumerate(sorted(list(s))} # dict{pair:index}
output_c = numpy.array([d[i,j] for i,j in zip(a,b)]).reshape(shp)
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 0],
[ 0, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 0],
[ 0, 1, 2, 2, 2, 4, 7, 7, 7, 7, 5, 0],
[ 0, 1, 2, 2, 2, 4, 7, 7, 7, 7, 5, 0],
[ 0, 1, 2, 2, 2, 3, 6, 6, 6, 6, 5, 0],
[ 0, 8, 9, 9, 9, 10, 6, 6, 6, 6, 5, 0],
[ 0, 0, 9, 9, 9, 10, 6, 6, 6, 6, 0, 0],
[ 0, 0, 9, 9, 9, 10, 6, 6, 6, 6, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])