Related
I have 10 customers and one depot 0. For each customer I now want to create a shuttle route from depot, to customer and back to depot in the following format:
Shuttle_route_i = [0, i, 0]
But I don't want to create a dictionary, because later the routes will be changed, compiled, etc.
Is there any way to get this?
My previous code was:
def Generierung_Pendelrouten (Koordinaten):
d = {}
for i in range(1, len(Koordinaten)):
d['Pendelroute_{0}'.format(i)] = [0,i,0]
return d
With the result:
Pendelrouten:
{'Pendelroute_1': [0, 1, 0], 'Pendelroute_2': [0, 2, 0], 'Pendelroute_3': [0, 3, 0], 'Pendelroute_4': [0, 4, 0], 'Pendelroute_5': [0, 5, 0], 'Pendelroute_6': [0, 6, 0], 'Pendelroute_7': [0, 7, 0], 'Pendelroute_8': [0, 8, 0], 'Pendelroute_9': [0, 9, 0], 'Pendelroute_10': [0, 10, 0]}
But with the dictionary I can't then continue to work as desired.
My other idea was to work with a for loop:
for i in range (1,11):
route = []
route.append(0)
route.append(i)
route.append(0)
print(route)
But then you get only the last route [0, 10, 0] output. This is the format in which I want to have all 10 routes.
Hey so i basically have a problem like this:
i have a numpy array which contains a matrix of values, for example:
Data = np.array([
[3, 0, 1, 5],
[0, 0, 0, 7],
[0, 3, 0, 0],
[0, 0, 0, 6],
[5, 1, 0, 0]])
Using another array i want to extract the specific values and sum them together, this is a bit hard to explain so ill just show an example:
values = np.array([3,1,3,4,2])
so this means we want the first 3 values of the first row, first value of the second row, first 3 values of the 3rd row, first 4 values of the 4th row and first 2 values of the the last row, so we only want this data:
final_data = np.array([
[3, 0, 1],
[0],
[0, 3, 0],
[0, 0, 0, 6],
[5, 1]])
then we want to get the sum amount of those values, in this case the sum value will be 19.
Is there any easy way to do this? also, the data isn't always the same size so i cant have any fixed variables.
An even better answer:
Data[np.arange(Data.shape[1])<values[:,None]].sum()
You can try:
sum([Data[i, :j].sum() for i, j in enumerate(values)])
You can accomplish this with advanced indexing. The advanced coordinates can be calculated separately before pulling them from the array.
Explicitly:
Data = np.array([
[3, 0, 1, 5],
[0, 0, 0, 7],
[0, 3, 0, 0],
[0, 0, 0, 6],
[5, 1, 0, 0]])
values = np.array([3,1,3,4,2])
X = [0,0,0,1,2,2,2,3,3,3,3,4,4]
Y = [0,1,2,0,0,1,2,0,1,2,3,0,1]
Data[X,Y]
Notice X is the number of times to access each row and Y is the column to access with each X. These can be calculated from values directly:
X = np.concatenate([[n]*i for n,i in enumerate(values)])
Y = np.concatenate([np.arange(i) for i in values])
I'm trying to make an array of 4x4 (16) pixel black and white images with all possible combinations. I made the following array as a template:
template = [[0,0,0,0], # start with all white pixels
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]]
I then want to iterate through the template and changing the 0 to 1 for every possible combination.
I tried to iterate with numpy and itertools but can only get 256 combinations, and with my calculations there should be 32000 (Edit: 65536! don't know what happened there...). Any one with mad skills that could help me out?
As you said, you can use the itertools module to do this, in particular the product function:
import itertools
import numpy as np
# generate all the combinations as string tuples of length 16
seq = itertools.product("01", repeat=16)
for s in seq:
# convert to numpy array and reshape to 4x4
arr = np.fromiter(s, np.int8).reshape(4, 4)
# do something with arr
You would have a total of 65536 such combinations of such a (4 x 4) shaped array. Here's a vectorized approach to generate all those combinations, to give us a (65536 x 4 x 4) shaped multi-dim array -
mask = ((np.arange(2**16)[:,None] & (1 << np.arange(16))) != 0)
out = mask.astype(int).reshape(-1,4,4)
Sample run -
In [145]: out.shape
Out[145]: (65536, 4, 4)
In [146]: out
Out[146]:
array([[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
...,
[[1, 0, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[0, 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, 1]]])
One possibility which relies on a for loop
out = []
for i in range(2**16):
out.append(np.frombuffer("{:016b}".format(i).encode('utf8')).view(np.uint8).reshape(4,4)-48)
Obviously you could make that a list comprehension if you like.
It takes advantage of Python string formatting which is able to produce the binary representation of integers. The format string instructs it to use 16 places filling with zeros on the left. The string is then encoded to give a bytes object which numpy can interpret as an array.
In the end we subtract the code for the character "0" to get a proper 0. Luckily, "1" sits just above "0", so that's all we need to do.
First I'll iterate for all numbers from 0 to (2^16)-1. Then I'll create a 16 character binary string for each of those numbers and thus covering all possible combinations
After that I converted the string to a list and made a 2d list out of it using list comprehension and slicing.
all_combinations = []
for i in xrange(pow(2,16))
binary = '{0:016b}'.format(i) ## Converted number to binary string
binary = map(int,list(binary)) ## String to list ## list(map(int,list(binary))) in py 3
template = [binary[i:i+4] for i in xrange(0, len(binary), 4)] #created 2d list
all_combinations.append(template)
I'm trying to make a nested list in Python to contain information about points in a video, and I'm having a lot of trouble creating an array for the results to be saved in to. The structure of the list is simple: the top level is a reference to the frame, the next level is a reference to a marker, and the last level is the point of the marker. So for example, the list is setup as such:
markerList # a long list of every marker in every frame
markerList[0] # every marker in the first frame
markerList[0][0] # the first marker of the first frame
markerList[0][0][0] # the x value of the first marker of the first frame
Calling markerList[0] looks like this:
array([[ 922.04443359, 903. ],
[ 987.83850098, 891.38830566],
[ 843.27374268, 891.70471191],
[ 936.38446045, 873.34661865],
[ 965.52880859, 840.44445801],
[ 822.19567871, 834.06298828],
[ 903.48956299, 830.62268066],
[ 938.70031738, 825.71557617],
[ 853.09545898, 824.47247314],
[ 817.84277344, 816.05029297],
[ 1057.91186523, 815.52935791],
[ 833.23632812, 787.48504639],
[ 924.24224854, 755.53997803],
[ 836.07800293, 720.02764893],
[ 937.83880615, 714.11199951],
[ 813.3493042 , 720.30566406],
[ 797.09521484, 705.72729492],
[ 964.31713867, 703.246521 ],
[ 934.9864502 , 697.27099609],
[ 815.1550293 , 688.91473389],
[ 954.94085693, 685.88171387],
[ 797.70239258, 672.35119629],
[ 877.05749512, 659.94250488],
[ 962.24786377, 659.26495361],
[ 843.66131592, 618.83868408],
[ 901.50476074, 585.42541504],
[ 863.41851807, 584.4977417 ]], dtype=float32)
The problem is that every frame contains a different number of markers. I want to create an empty array the same length as markerList (i.e., the same number of frames) in which every element is the same size as the largest frame in markerList. Some important caveats: first,I want to save the results into a .mat file where the final array (which I'll call finalStack) is a cell of cells. Second, I need to be able to reference and assign to any specific part of finalStack. So if I want to move a point to finalStack[0][22], I need to be able to do so without conflict. This basically just means I can't use append methods anywhere, but it's also unearthed my first problem - finding a way to create finalStack that doesn't cause every new assignment to be duplicated throughout the entire parent list. I've tried to do this a few different ways, and none work correctly.
Attempts at a solution:
Following another SO question, I attempted to create finalStack iteratively, but to no avail. I created the following function:
def createFinalStack(numMarkers, numPoints, frames):
step = [[0]*numPoints for x in xrange(numMarkers)]
finalStack = [step]*frames
return finalStack
However, this causes all assignments to be copied across the parent list, such that assigning finalStack[0][12] leads to finalStack[2][12] == finalStack[20][12] == finalStack[0][12]. In this example, numMarkers= 40, numPoints = 2 (just x & y), and frames= 200. (So the final array should be 200 x 40 x 2.)
That said, this seems like the most straightforward way to do what I want, I just can't get past the copy error (I know it's a reference issue, I just don't know how to avoid it in this context).
Another seemingly simple solution would be to copy markerList using copy.deepcopy(markerList), and pad any frames with less than 40 markers to get them to numMarkers = 40, and zero out anything else. But I can't come up with a good way to cycle through all of the frames, add points in the correct format, and then empty out everything else.
If this isn't enough information to work with, I can try to provide greater context and some other not-good-methods that didn't work at all. I've been stuck on this long enough that I'm convinced the solution is horribly simple, and I'm just missing the obvious. I hope you can prove me right!
Thanks!
This illustrates what is going on:
In [1334]: step=[[0]*3 for x in range(3)]
In [1335]: step
Out[1335]: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
In [1336]: stack=[step]*4
In [1337]: stack
Out[1337]:
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [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 [1338]: stack[0]
Out[1338]: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
In [1339]: stack[0][2]=3
In [1340]: stack
Out[1340]:
[[[0, 0, 0], [0, 0, 0], 3],
[[0, 0, 0], [0, 0, 0], 3],
[[0, 0, 0], [0, 0, 0], 3],
[[0, 0, 0], [0, 0, 0], 3]]
In [1341]: step
Out[1341]: [[0, 0, 0], [0, 0, 0], 3]
When you use alist*n to create new list, the new list contains multiple pointers to the same underlying object. As a general rule, using *n to replicate a list is dangerous if you plan on changing values later on.
If instead I make an array of the right dimensions I don't have this problem:
In [1342]: np.zeros((4,3,3),int)
Out[1342]:
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
...
[0, 0, 0]]])
Or in list form:
In [1343]: np.zeros((4,3,3),int).tolist()
Out[1343]:
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
If I assign a value in this list, I only change one item:
In [1344]: stack=np.zeros((4,3,3),int).tolist()
In [1345]: stack[0][2]=3
In [1346]: stack
Out[1346]:
[[[0, 0, 0], [0, 0, 0], 3],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
I really should have used stack[0][2][1]=3, but you get the idea. If I make the same assignment in the array form I end up changing a whole row
In [1347]: stack=np.zeros((4,3,3),int)
In [1348]: stack[0][2]=3
In [1349]: stack
Out[1349]:
array([[[0, 0, 0],
[0, 0, 0],
[3, 3, 3]],
[[0, 0, 0],
...
[0, 0, 0]]])
I should have used an expression like stack[0,2,:]=4.
It's probably possible to construct a triply next list like this where all initial values are independent. But this array approach is simpler.
I have a sparse matrix (numpy.array) and I would like to have the index of the nonzero elements in it.
In Matlab I would write:
[i, j] = find(CM)
and in Python what should I do?
I have tried numpy.nonzero (but I don't know how to take the indices from that) and flatnonzero (but it's not convenient for me, I need both the row and column index).
Thanks in advance!
Assuming that by "sparse matrix" you don't actually mean a scipy.sparse matrix, but merely a numpy.ndarray with relatively few nonzero entries, then I think nonzero is exactly what you're looking for. Starting from an array:
>>> a = (np.random.random((5,5)) < 0.10)*1
>>> a
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[1, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
nonzero returns the indices (here x and y) where the nonzero entries live:
>>> a.nonzero()
(array([1, 2, 3]), array([4, 2, 0]))
We can assign these to i and j:
>>> i, j = a.nonzero()
We can also use them to index back into a, which should give us only 1s:
>>> a[i,j]
array([1, 1, 1])
We can even modify a using these indices:
>>> a[i,j] = 2
>>> a
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 2],
[0, 0, 2, 0, 0],
[2, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
If you want a combined array from the indices, you can do that too:
>>> np.array(a.nonzero()).T
array([[1, 4],
[2, 2],
[3, 0]])
(there are lots of ways to do this reshaping; I chose one almost at random.)
This goes slightly beyond what you as and I only mention it since I once faced a similar problem. If you want the indices to access some other array there is some very simple sytax:
import numpy as np
array = np.random.randint(0, 2, size=(3, 3))
data = np.random.random(size=(3, 3))
Now array looks something like
>>> print array
array([[0, 1, 0],
[1, 0, 1],
[1, 1, 0]])
while data could be
>>> print data
array([[ 0.92824816, 0.43605604, 0.16627849],
[ 0.00301434, 0.94342538, 0.95297402],
[ 0.32665135, 0.03504204, 0.86902492]])
Then if we want the elements of data which are zero:
>>> print data[array==0]
array([ 0.92824816, 0.16627849, 0.94342538, 0.86902492])
Which is nice and simple.