Matching two lists values and appending to dictionary - python-3.x

I have a list of nodes with their coordinates of the form
MCoord = [[Node1,X,Y,Z],[Node2,X,Y,Z]...]
Coordinates:
MCoord = [
[1, 0, 0, 0],
[2, 0, 1000, 1300],
[3, 0, 2000, 2000],
[4, 0, 3000, 2500],
[5, 0, 4000, 3200],
[6, 0, 5000, 4200],
[7, 0, 6000, 6000],
[8, 1000, 0, 0],
[9, 1000, 1000, 1300],
[10, 1000, 2000, 2000],
[11, 1000, 3000, 2500],
[12, 1000, 4000, 3200],
[13, 1000, 5000, 4200],
[14, 1000, 6000, 6000],
[15, 2000, 0, 0],
[16, 2000, 1000, 1300],
// ...
[27, 3500, 5000, 4200],
[28, 3500, 6000, 6000]
]
I want to store all nodes (with their coordinates) of the same X coordinate and matching the corresponding key value under the keys S1 (all nodes with same X value), S2, S3 and so on.
Script:
SectionLocation = {'S1':0 , 'S2':1000 , 'S3':2000 , 'S4':3500}
SectionComplete = {'S1':0 , 'S2':0 , 'S3':0 , 'S4':0}
k = 0
for i in range(len(MCoord)):
print(i)
if MCoord[i][1] == SectionLocation[k]:
keydic = get_key(SectionLocation[k])
SectionComplete[keydic].append(MCoord[i])
print(SectionComplete)
else:
k = k + 1
print(SectionComplete)
I cannot seem to be able to append new values to the dictionnary. Any advice ?
Desired outpput:
SectionComplete = {
'S1' : [
[1, 0, 0, 0],
[2, 0, 1000, 1300],
[3, 0, 2000, 2000],
[4, 0, 3000, 2500],
[5, 0, 4000, 3200],
[6, 0, 5000, 4200],
[7, 0, 6000, 6000]
],
'S2' : [
[8, 1000, 0, 0],
[9, 1000, 1000, 1300],
[10, 1000, 2000, 2000],
[11, 1000, 3000, 2500],
[12, 1000, 4000, 3200],
[13, 1000, 5000, 4200],
[14, 1000, 6000, 6000]
],
// ...
}

I believe this is what you are attempting to achieve. But you can correct me if I'm wrong.
# your list of nodes and coordinates
MCoord = [[1, 0, 0, 0],
[2, 0, 1000, 1300],
[3, 0, 2000, 2000],
[4, 0, 3000, 2500],
[5, 0, 4000, 3200],
[6, 0, 5000, 4200],
[7, 0, 6000, 6000],
[8, 1000, 0, 0],
[9, 1000, 1000, 1300],
[10, 1000, 2000, 2000],
[11, 1000, 3000, 2500],
[12, 1000, 4000, 3200],
[13, 1000, 5000, 4200],
[14, 1000, 6000, 6000],
[15, 2000, 0, 0],
[16, 2000, 1000, 1300]]
# a dictionary mapping of section to its ID
SectionLocation = {0: 'S1', 1000: 'S2', 2000: 'S3', 3500: 'S4'}
# A dictionary of the grouped sections
SectionComplete = {'S1': [], 'S2': [], 'S3': [], 'S4': []}
# we don't need the index since python for loops take care of that for us
for node in MCoord:
# grab the relevant section from the mapping
section = SectionLocation[node[1]]
# append it to that sections empty list
SectionComplete[section].append(node)
print(SectionComplete)
In your example here SectionComplete = {'S1':0 , 'S2':0 , 'S3':0 , 'S4':0} you initialize your dict values to ints and then are trying to append to those ints. Essentially it's like trying to do something like this.
my_int = 0
my_int.append(23)
This won't work because an int does not have an append method.

MCoord = [[...]]
import numpy as np
array_of_coords = np.array((MCoord))
uniq_X = np.unique(array_of_coords[:,1])
group_by_X = [[array_of_coords[array_of_coords[:,1]==i,:] for i in uniq_X]]
list_of_keys = ["S"+str(i) for i in range(len(uniq_X))]
dictionary = dict(zip(list_of_keys, group_by_X[0]))
print(dictionary)
out:
{'S0': array([[ 1, 0, 0, 0],
[ 2, 0, 1000, 1300],
[ 3, 0, 2000, 2000],
[ 4, 0, 3000, 2500],
[ 5, 0, 4000, 3200],
[ 6, 0, 5000, 4200],
[ 7, 0, 6000, 6000]]), 'S1': array([[ 8, 1000, 0, 0],
[ 9, 1000, 1000, 1300],
[ 10, 1000, 2000, 2000],
[ 11, 1000, 3000, 2500],
[ 12, 1000, 4000, 3200],
[ 13, 1000, 5000, 4200],
[ 14, 1000, 6000, 6000]]), 'S2': array([[ 15, 2000, 0, 0],
[ 16, 2000, 1000, 1300]])}

Related

Turn off visibility of axis and grids in python plotly "go.Scatter3d"

import numpy as np
xx= np.array([[ 0, 0, 0], [ 0, 5, 0], [ 4, 5, -4], [ 4, 0, 0], [ 0, 0, -4],
[ 0, 5, -4],[ 4, 5, 0], [ 4, 0, -4], [ 8, 5, -4], [ 8, 0, 0], [ 8, 5, 0],
[ 8, 0, -4], [ 4, 10, -4], [ 4, 10, 0], [ 8, 10, -4], [ 8, 10, 0]])
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=xx[:,2],y=xx[:,0],z=xx[:,1],mode='markers'))
fig.show()
enter image description here
Just want to see the points, removing all axis and gridlines.
You can use scene attribute as follows:
import numpy as np
xx= np.array([[ 0, 0, 0], [ 0, 5, 0], [ 4, 5, -4], [ 4, 0, 0], [ 0, 0, -4],
[ 0, 5, -4],[ 4, 5, 0], [ 4, 0, -4], [ 8, 5, -4], [ 8, 0, 0], [ 8, 5, 0],
[ 8, 0, -4], [ 4, 10, -4], [ 4, 10, 0], [ 8, 10, -4], [ 8, 10, 0]])
fig = go.Figure()
fig.add_trace(go.Scatter3d(x=xx[:,2],y=xx[:,0],z=xx[:,1],mode='markers'))
fig.update_layout(scene = dict(xaxis = dict(showgrid = False,showticklabels = False),
yaxis = dict(showgrid = False,showticklabels = False),
zaxis = dict(showgrid = False,showticklabels = False)
))
fig.show()

2D Array Slice Assignment in loop not working as expected?

Below is the code
code for slice assignment
For loop is used to assign lists to slice of list from main 2d list
But the output is not as expected.
qu = [[1, 2, 100], [2, 5, 100], [3, 4, 100]]
n=5
a = [[0]*n]*len(qu)
for i in range(len(qu)):
p=qu[i][0]-1
q=qu[i][1]
a[i][p:q]=[qu[i][2]]*(q-p)
print(a)
Output ---
[[100, 100, 0, 0, 0], [100, 100, 0, 0, 0], [100, 100, 0, 0, 0]]
[[100, 100, 100, 100, 100], [100, 100, 100, 100, 100], [100, 100, 100, 100, 100]]
[[100, 100, 100, 100, 100], [100, 100, 100, 100, 100], [100, 100, 100, 100, 100]]
Expected Output --
[[100, 100, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[[100, 100, 0, 0, 0], [0, 100, 100, 100, 100], [0, 0, 0, 0, 0]]
[[100, 100, 0, 0, 0], [0, 100, 100, 100, 100], [0, 0, 100, 100, 0]]
Blockquote

Using dijkstra_path function in networkx library

I'm using networkx library to find shortest path between two nodes using dijkstra algo as follows
import networkx as nx
A = [[0, 100, 0, 0 , 40, 0],
[100, 0, 20, 0, 0, 70],
[0, 20, 0, 80, 50, 0],
[0, 0, 80, 0, 0, 30],
[40, 0, 50, 0, 0, 60],
[0, 70, 0, 30, 60, 0]];
print(nx.dijkstra_path(A, 0, 4))
In the above code I'm using matrix directly, But library requires graph to be created as follows
G = nx.Graph()
G = nx.add_node(<node>)
G.add_edge(<node 1>, <node 2>)
It is very time consuming to create matrix by using above commands. Is there any way to give input as weighted matrix to the dijkstra_path function.
First you need to convert your adjacency matrix to a numpy matrix with np.array.
Then you can simply create your graph with from_numpy_matrix.
import networkx as nx
import numpy as np
A = [[0, 100, 0, 0 , 40, 0],
[100, 0, 20, 0, 0, 70],
[0, 20, 0, 80, 50, 0],
[0, 0, 80, 0, 0, 30],
[40, 0, 50, 0, 0, 60],
[0, 70, 0, 30, 60, 0]]
a = np.array(A)
G = nx.from_numpy_matrix(a)
print(nx.dijkstra_path(G, 0, 4))
Output:
[0, 4]
Side note: you can check the graph edges with the following code.
for edge in G.edges(data=True):
print(edge)
Output:
(0, 1, {'weight': 100})
(0, 4, {'weight': 40})
(1, 2, {'weight': 20})
(1, 5, {'weight': 70})
(2, 3, {'weight': 80})
(2, 4, {'weight': 50})
(3, 5, {'weight': 30})
(4, 5, {'weight': 60})

how to assign non contiguous labels of one numpy array to another numpy array and add accordingly?

I have the following labels
>>> lab
array([3, 0, 3 ,3, 1, 1, 2 ,2, 3, 0, 1,4])
I want to assign this label to another numpy array i.e
>>> arr
array([[81, 1, 3, 87], # 3
[ 2, 0, 1, 0], # 0
[13, 6, 0, 0], # 3
[14, 0, 1, 30], # 3
[ 0, 0, 0, 0], # 1
[ 0, 0, 0, 0], # 1
[ 0, 0, 0, 0], # 2
[ 0, 0, 0, 0], # 2
[ 0, 0, 0, 0], # 3
[ 0, 0, 0, 0], # 0
[ 0, 0, 0, 0], # 1
[13, 2, 0, 11]]) # 4
and add all corresponding rows with same labels.
The output must be
([[108, 7, 4,117]--3
[ 0, 0, 0, 0]--0
[ 0, 0, 0, 0]--1
[ 0, 0, 0, 0]--2
[13, 2, 0, 11]])--4
You could use groupby from pandas:
import pandas as pd
parr=pd.DataFrame(arr,index=lab)
pd.groupby(parr,by=parr.index).sum()
0 1 2 3
0 2 0 1 0
1 0 0 0 0
2 0 0 0 0
3 108 7 4 117
4 13 2 0 11
numpy doesn't have a group_by function like pandas, but it does have a reduceat method that performs fast array actions on groups of elements (rows). But it's application in this case is a bit messy.
Start with our 2 arrays:
In [39]: arr
Out[39]:
array([[81, 1, 3, 87],
[ 2, 0, 1, 0],
[13, 6, 0, 0],
[14, 0, 1, 30],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[13, 2, 0, 11]])
In [40]: lbls
Out[40]: array([3, 0, 3, 3, 1, 1, 2, 2, 3, 0, 1, 4])
Find the indices that will sort lbls (and rows of arr) into contiguous blocks:
In [41]: I=np.argsort(lbls)
In [42]: I
Out[42]: array([ 1, 9, 4, 5, 10, 6, 7, 0, 2, 3, 8, 11], dtype=int32)
In [43]: s_lbls=lbls[I]
In [44]: s_lbls
Out[44]: array([0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4])
In [45]: s_arr=arr[I,:]
In [46]: s_arr
Out[46]:
array([[ 2, 0, 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],
[81, 1, 3, 87],
[13, 6, 0, 0],
[14, 0, 1, 30],
[ 0, 0, 0, 0],
[13, 2, 0, 11]])
Find the boundaries of these blocks, i.e. where s_lbls jumps:
In [47]: J=np.where(np.diff(s_lbls))
In [48]: J
Out[48]: (array([ 1, 4, 6, 10], dtype=int32),)
Add the index of the start of the first block (see the reduceat docs)
In [49]: J1=[0]+J[0].tolist()
In [50]: J1
Out[50]: [0, 1, 4, 6, 10]
Apply add.reduceat:
In [51]: np.add.reduceat(s_arr,J1,axis=0)
Out[51]:
array([[ 2, 0, 1, 0],
[ 0, 0, 0, 0],
[ 0, 0, 0, 0],
[108, 7, 4, 117],
[ 13, 2, 0, 11]], dtype=int32)
These are your numbers, sorted by lbls (for 0,1,2,3,4).
With reduceat you could take other actions like maximum, product etc.

Getting an unknown parse error with flot

Can someone please point out what I'm missing here? I'm trying to generate a flot chart with the following function (which is called on success of the $.getJSON function in the page). At the moment, the chart is not loading at all and I get a parse error. If I removed this function, the parse error disappears, so I'm sure it's this function causing the problem but I can't see where!
function plotLineGraph(theData){
var myData = theData['data'];
var myDates = theData['dates'];
var d1 = [
myData[0], myData[1], myData[2], myData[3], myData[4],
myData[5], myData[6], myData[7], myData[8], myData[9],
myData[10], myData[11], myData[12], myData[13], myData[14],
myData[15], myData[16], myData[17], myData[18], myData[19],
myData[20], myData[21], myData[22], myData[23], myData[24],
myData[25], myData[26], myData[27], myData[28], myData[29]
];
$.plot($("#placeholder"), [
{label: "rating", data: d1}
], {
series: {
lines: { show: true },
points: { show: true }
},
xaxis: {
ticks:[
myDates[0], myDates[1], myDates[2], myDates[3], myDates[4],
myDates[5], myDates[6], myDates[7], myDates[8], myDates[9],
myDates[10], myDates[11], myDates[12], myDates[13], myDates[14],
myDates[15], myDates[16], myDates[17], myDates[18], myDates[19],
myDates[20], myDates[21], myDates[22], myDates[23], myDates[24],
myDates[25], myDates[26], myDates[27], myDates[28], myDates[29]
]
},
yaxis: {
ticks: 5,
min: 0,
max: 5
},
grid: {
backgroundColor: { colors: ["#fff", "#eee"] }
}
});
}
EDIT:
The $.getJSON function returns the following JSON:
{
"data": [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], [19, 0], [20, 0], [21, 0], [22, 0], [23, 3], [24, 3], [25, 2], [26, 0], [27, 0], [28, 0], [29, 0], [30, 0]],
"dates": [[1, '10/9'], [2, '11/9'], [3, '12/9'], [4, '13/9'], [5, '14/9'], [6, '15/9'], [7, '16/9'], [8, '17/9'], [9, '18/9'], [10, '19/9'], [11, '20/9'], [12, '21/9'], [13, '22/9'], [14, '23/9'], [15, '24/9'], [16, '25/9'], [17, '26/9'], [18, '27/9'], [19, '28/9'], [20, '29/9'], [21, '30/9'], [22, '1/10'], [23, '2/10'], [24, '3/10'], [25, '4/10'], [26, '5/10'], [27, '6/10'], [28, '7/10'], [29, '8/10'], [30, '9/10']]
}
EDIT 2:
Thanks Brendan. The call is here (it is part of a larger function which uses the same syntax to correctly generate a few other pie charts):
$.getJSON('/last-month-daily-average-for-products/'
+ theProductUuid + '/', plotLineGraph);
As for the disassembling/reassembling of the JSON.... No particular reason, no. All I need to do is get the relevant data from the JSON into the correct parts of the flot function, so feel free to correct anything which is inefficient as well as incorrect!!
There's nothing wrong with any of the code you have provided. It works perfectly.
See it in action here: http://jsfiddle.net/ryleyb/eJ2h8/

Resources