Why are my matrix values being reset back to 1? - python

I can't seem to figure out why the values of the first column after the 3 are being reset to 1 and then 1 again. I think it has to do with the not 999 if statement, but I'm not sure what to add or change. Any help is appreciated thank you!
n = 15 #the number the matrices will be an n*n of
a = [[ 0 for x in range(n)] for x in range(n)]
a[-1][-1] =111
a[0][3] =999
def Manhattan(x):
k = 1
m = 1
for i in range(n):
for j in range(n):
if (x[i][j] < 1):
if (x[j][i] < 1):
if (x[i][j-1] != 999 or x[j-1][i] !=999 ):
k = x[i][j-1]
x[i][j] = k + 1
m = x[j-1][i]
x[j][i] = m + 1
else:
k = x[i][j]
x[i][j] = k + 1
for row in x:
print()
for val in row:
print('%4d' %val, end = " ")
Manhattan(a)

im not completely sure what your program is meant to do but i think this is what youre trying to achieve as output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
code:
n = 15 #the number the matrices will be an n*n of
a = [[ 0 for x in range(n)] for x in range(n)]
a[-1][-1] = 111
a[0][3] = 999
def Manhattan(x1):
start_value = 0
for x in range(n):
start_value += 1
second_val = start_value
for y in range(n):
x1[y][x] = second_val
second_val += 1
for line in x1:
for char in line:
print('%4d' %char, end = " ")
print()
Manhattan(a)
your code is fairly unorganized it makes it hard to understand but if this was your goal then what you need to do is increment a value starting from 1 by 1 each outer loop while looping through the matrix and then every iteration of the inner loop you increase it by 1 and set the value into the corresponding index.

I think your question is why x[0][3] equals 1 after calling the function Manhattan, well that because your else statement is compare with if (x[j][i] < 1) statement.
So, when the code go on x[3][0], the if (x[0][3]) will equal False,
then go to the else statement, that means: k=x[3][0]=0, and then x[3][0]=0+1=1.
I'm not sure if this output is your expectation:
1 2 3 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
15 16 17 18 19 20 21 22 23 24 25 26 27 28 111
Code:
def Manhattan(x):
for i in range(n):
for j in range(n):
if x[i][j] == 111:
break
up = 0
left = 0
if x[i-1][j] > 0 and bool(i):
up = x[i-1][j]
if x[i][j-1] > 0 and bool(j):
left = x[i][j-1]
if bool(up) and bool(left):
x[i][j] = x[i][j] + min(up, left) + 1
elif bool(up):
x[i][j] = x[i][j] + up + 1
elif bool(left):
x[i][j] = x[i][j] + left + 1
else:
x[i][j] = x[i][j] + 1
for row in x:
print()
for val in row:
print('%4d' %val, end = " ")

Figured it out myself! The issue was that when checking j-1 != 999 it was eqaul to 999 for x[0][3] so it would never fill out those elements correctly. Fixed it by changing the else statement and adding in a second if statement for j-1 == 999
n = 10 #the number the matrices will be an n*n of
a = [[ 0 for x in range(n)] for x in range(n)]
a[-1][-1] =111
a[0][6] =999
def Manhattan(x):
k = 1
m = 1
for i in range(n):
for j in range(n):
if (x[i][j] < 1):
if (x[j][i] < 1):
if (x[i][j-1] != 999 and x[j-1][i] !=999 ):
k = x[i][j-1]
x[i][j] = k + 1
m = x[j-1][i]
x[j][i] = m + 1
if (x[i][j-1] == 999 or x[j-1][i] ==999 ):
k = x[i][j-2]
x[i][j] = k + 4
m = x[j-2][i]
x[j][i] = m + 2
else:
k = x[i][j]
x[i][j] = k + 4
for row in x:
print()
for val in row:
print('%4d' %val, end = " ")
Manhattan(a)

Related

combining specific row conditionally and add output to existing row in pandas

suppose I have following data frame :
data = {'age' :[10,11,12,11,11,10,11,13,13,13,14,14,15,15,15],
'num1':[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
'num2':[20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]}
df = pd.DataFrame(data)
I want to sum rows for age 14 and 15 and keep those new values as age 14. my expected output would be like this:
age time1 time2
1 10 10 20
2 11 11 21
3 12 12 22
4 11 13 23
5 11 14 24
6 10 15 25
7 11 16 26
8 13 17 27
9 13 18 28
10 13 19 29
11 14 110 160
in the code below, I have tried to group.by age but it does not work for me:
df1 =df.groupby(age[age >=14])['num1', 'num2'].apply(', '.join).reset_index(drop=True).to_frame()
limit_age = 14
new = df.query("age < #limit_age").copy()
new.loc[len(new)] = [limit_age,
*df.query("age >= #limit_age").drop(columns="age").sum()]
first get the "before 14" dataframe
then assign it to a new row where
age is 14
other values are the row-wise sums of "after 14" dataframe
to get
>>> new
age num1 num2
0 10 10 20
1 11 11 21
2 12 12 22
3 11 13 23
4 11 14 24
5 10 15 25
6 11 16 26
7 13 17 27
8 13 18 28
9 13 19 29
10 14 110 160
(new.index += 1 can be used for a 1-based index at the end.)
I would use a mask and concat:
m = df['age'].isin([14, 15])
out = pd.concat([df[~m],
df[m].agg({'age': 'min', 'num1': 'sum', 'num2': 'sum'})
.to_frame().T
], ignore_index=True)
Output:
age num1 num2
0 10 10 20
1 11 11 21
2 12 12 22
3 11 13 23
4 11 14 24
5 10 15 25
6 11 16 26
7 13 17 27
8 13 18 28
9 13 19 29
10 14 110 160

create dataframe with increasing numbers in python

I want to create the following dataframe: n is the number of rows, and m is the columns.
In R, this would be generated by:
ia=array((1:m),c(m,n))
But I do not know how i can achieve the same in python.
Kind regards,
Use numpy.broadcast_to with DataFrame constructor:
m = 24
n = 13
df = pd.DataFrame(np.broadcast_to(np.arange(1, m + 1)[:, None], (m, n)))
print (df)
0 1 2 3 4 5 6 7 8 9 10 11 12
0 1 1 1 1 1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 2 2 2 2 2 2 2
2 3 3 3 3 3 3 3 3 3 3 3 3 3
3 4 4 4 4 4 4 4 4 4 4 4 4 4
4 5 5 5 5 5 5 5 5 5 5 5 5 5
5 6 6 6 6 6 6 6 6 6 6 6 6 6
6 7 7 7 7 7 7 7 7 7 7 7 7 7
7 8 8 8 8 8 8 8 8 8 8 8 8 8
8 9 9 9 9 9 9 9 9 9 9 9 9 9
9 10 10 10 10 10 10 10 10 10 10 10 10 10
10 11 11 11 11 11 11 11 11 11 11 11 11 11
11 12 12 12 12 12 12 12 12 12 12 12 12 12
12 13 13 13 13 13 13 13 13 13 13 13 13 13
13 14 14 14 14 14 14 14 14 14 14 14 14 14
14 15 15 15 15 15 15 15 15 15 15 15 15 15
15 16 16 16 16 16 16 16 16 16 16 16 16 16
16 17 17 17 17 17 17 17 17 17 17 17 17 17
17 18 18 18 18 18 18 18 18 18 18 18 18 18
18 19 19 19 19 19 19 19 19 19 19 19 19 19
19 20 20 20 20 20 20 20 20 20 20 20 20 20
20 21 21 21 21 21 21 21 21 21 21 21 21 21
21 22 22 22 22 22 22 22 22 22 22 22 22 22
22 23 23 23 23 23 23 23 23 23 23 23 23 23
23 24 24 24 24 24 24 24 24 24 24 24 24 24
df = df.rename(index = lambda x: x+1, columns=lambda x: x+1)
print (df)
1 2 3 4 5 6 7 8 9 10 11 12 13
1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9 9 9 9 9 9
10 10 10 10 10 10 10 10 10 10 10 10 10 10
11 11 11 11 11 11 11 11 11 11 11 11 11 11
12 12 12 12 12 12 12 12 12 12 12 12 12 12
13 13 13 13 13 13 13 13 13 13 13 13 13 13
14 14 14 14 14 14 14 14 14 14 14 14 14 14
15 15 15 15 15 15 15 15 15 15 15 15 15 15
16 16 16 16 16 16 16 16 16 16 16 16 16 16
17 17 17 17 17 17 17 17 17 17 17 17 17 17
18 18 18 18 18 18 18 18 18 18 18 18 18 18
19 19 19 19 19 19 19 19 19 19 19 19 19 19
20 20 20 20 20 20 20 20 20 20 20 20 20 20
21 21 21 21 21 21 21 21 21 21 21 21 21 21
22 22 22 22 22 22 22 22 22 22 22 22 22 22
23 23 23 23 23 23 23 23 23 23 23 23 23 23
24 24 24 24 24 24 24 24 24 24 24 24 24 24
You can use np.repeat or np.tile
n = 5 # 13
m = 8 # 24
# Enhanced by #mozway
df = pd.DataFrame(np.tile(np.arange(1, m+1),(n, 1)).T)
# OR
df = pd.DataFrame(np.repeat(np.arange(1, m+1), m).reshape(-1, m))
print(df)
# Output
0 1 2 3 4
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
4 5 5 5 5 5
5 6 6 6 6 6
6 7 7 7 7 7
7 8 8 8 8 8

How to impoving the layout of networkx barbell graph?

I want to draw a barbell graph Barbell(10,10) with edgelist
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 4
3 5
3 6
3 7
3 8
3 9
4 5
4 6
4 7
4 8
4 9
5 6
5 7
5 8
5 9
6 7
6 8
6 9
7 8
7 9
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
20 22
20 23
20 24
20 25
20 26
20 27
20 28
20 29
21 22
21 23
21 24
21 25
21 26
21 27
21 28
21 29
22 23
22 24
22 25
22 26
22 27
22 28
22 29
23 24
23 25
23 26
23 27
23 28
23 29
24 25
24 26
24 27
24 28
24 29
25 26
25 27
25 28
25 29
26 27
26 28
26 29
27 28
27 29
28 29
I use the following code to visiualize this graph:
import numpy as np
import networkx as nx
barbell = nx.read_edgelist('graph/barbell.edgelist')
classes = [0,] * len(gnx.nodes)
nonzero = m2 + 2
first = range(1, (nonzero + 1) // 2 + 1)
second = reversed(range(1, nonzero - len(first) + 1))
classes[m1 - 1 : (m1 + m2) + 1] = list(first) + list(second)
nx.draw(gnx, node_color=classes, cmap="jet")
Then, I can get the image as follows:
However, this paper struc2vec, use same edges and draw a good layout as follows:
So is it possible use networkx to impove the layout of barbell graph like above? Or need I use another tools?
This should get you started.
import networkx as nx
import matplotlib.pyplot as plt
n_clique, n_path = 10, 10
clique1 = nx.complete_graph(n_clique)
clique1_pos = nx.circular_layout(clique1)
clique2 = nx.complete_graph(n_clique)
clique2_mapping = {node: node + n_clique for node in clique2}
nx.relabel_nodes(clique2, clique2_mapping, copy=False) # avoids repeated nodes
x_diff, y_diff = 8, -1
clique2_pos = {node: clique1_pos[node-n_clique] + (x_diff, y_diff) for node in clique2}
path = nx.path_graph(n_path)
path_mapping = {node: node + 2 * n_clique for node in path}
nx.relabel_nodes(path, path_mapping, copy=False) # avoids repeated nodes
path_nodes = list(path.nodes)
path_half1_nodes = path_nodes[:n_path//2]
path_half2_nodes = path_nodes[n_path//2:]
path_dist = 0.9
clique2_entry = n_clique + n_clique // 2
path_half1_pos = {node: clique1_pos[0] + (path_dist + i * path_dist, 0) for i, node in enumerate(path_half1_nodes)}
path_half2_pos = {node: clique2_pos[clique2_entry] - (path_dist + i * path_dist, 0) for i, node in enumerate(path_half2_nodes[::-1])}
path_pos = {**path_half1_pos, **path_half2_pos}
barbell = nx.Graph()
barbell.add_edges_from(clique1.edges)
barbell.add_edges_from(clique2.edges)
barbell.add_edges_from(path.edges)
barbell.add_edges_from([(path_half1_nodes[0], 0), (path_half2_nodes[-1], clique2_entry)])
clique_pos = {**clique1_pos, **clique2_pos}
barbell_pos = {**clique_pos, **path_pos}
plt.figure(figsize=(20, 6))
nx.draw(barbell, pos=barbell_pos, with_labels=True)
Output

How to add values by column into a Dataframe

I have a Dataframe with three columns store, hour, count. The problem I'm facing is some hours are missing for some stores and I want them to be 0.
This is how the dataframe looks like
# store_id hour count
# 0 13 0 56
# 1 13 1 78
# 2 13 2 53
# 3 23 13 14
# 4 23 14 13
As you can see for the store with id 13 doesn't have values for hours 3-23, similarly with store 23 it doesn't have values for many other hours.
I tried to solve this by creating a temporal dataframe with two columns id and count and performing a right outer join, but didn't work.
If typo and no duplicates in hour per groups, solution is reindex with MultiIndex.from_product:
df = df.set_index(['store_id','hour'])
mux = pd.MultiIndex.from_product([df.index.levels[0], range(23)], names=df.index.names)
df = df.reindex(mux, fill_value=0).reset_index()
print (df)
store_id hour count
0 13 0 56
1 13 1 78
2 13 2 53
3 13 3 0
4 13 4 0
5 13 5 0
6 13 6 0
7 13 7 0
8 13 8 0
9 13 9 0
10 13 10 0
11 13 11 0
12 13 12 0
13 13 13 0
14 13 14 0
15 13 15 0
16 13 16 0
17 13 17 0
18 13 18 0
19 13 19 0
20 13 20 0
21 13 21 0
22 13 22 0
23 23 0 0
24 23 1 0
25 23 2 0
26 23 3 0
27 23 4 0
28 23 5 0
29 23 6 0
30 23 7 0
31 23 8 0
32 23 9 0
33 23 10 0
34 23 11 0
35 23 12 0
36 23 13 14
37 23 14 0
38 23 15 0
39 23 16 0
40 23 17 0
41 23 18 0
42 23 19 0
43 23 20 0
44 23 21 0
45 23 22 0
Try this:
all_hours = set(range(24))
for sid in set(df['store_id']):
misshours = list(all_hours - set(df['hour'][df['store_id'] == sid]))
nmiss = len(misshours)
df = pandas.concat([df, DataFrame({'store_id': nmiss * [sid], misshours, 'count': nmiss * [0]})])

Task is create a table which contain 2 lines, where each value is sum of all numbers between 2 lines. Solve the program with funtction

Prompt from use two values A and B. Produce table AxB, where each value is sum of all numbers between A and B, (or B and A if B < A). Create functions to generate each line, and function to print all lines.
I solve this problem by using "if" operator, but I don't know how to solve by using function. My way:
a = input("Enter A:")
b = input("Enter B:")
k = 0
for i in range(1,a+1):
for j in range(1,b+1):
if i != j:
k = 0
if j < i:
m = j
ma = i
else:
m = i
ma = j
for m in range(m,ma+1):
k += m
print k,
else:
print i,
print
Simple sample:
Enter A: 3
Enter B: 4
Result should be:
1 3 6 10
3 2 5 9
6 5 3 7
This is probably what you would want
from itertools import product
from math import log10
def foo(row, col):
table = [[0]*col for _ in range(row)]
for i, j in product(range(row), range(col)):
table[i][j] = sum(range(i+1, j+2)) if i < j else sum(range(j+1, i+2))
_max = max(row, col)
_max = int(log10(_max*(_max+1) / 2)) + 3
formatstr = ("{{:^{}}}".format(_max))*col
for row in table:
print formatstr.format(*row)
>>> foo(3,4)
1 3 6 10
3 2 5 9
6 5 3 7
>>> foo(10,10)
1 3 6 10 15 21 28 36 45 55
3 2 5 9 14 20 27 35 44 54
6 5 3 7 12 18 25 33 42 52
10 9 7 4 9 15 22 30 39 49
15 14 12 9 5 11 18 26 35 45
21 20 18 15 11 6 13 21 30 40
28 27 25 22 18 13 7 15 24 34
36 35 33 30 26 21 15 8 17 27
45 44 42 39 35 30 24 17 9 19
55 54 52 49 45 40 34 27 19 10

Categories