How to create a distance matrix between two places - python

I have a dataframe that looks like this
origin Destination distance
x1 y1 d11
x2 y1 d21
x3 y1 d31
x1 y2 d12
x2 y2 d22
x3 y2 d32
x1 y3 d13
x2 y3 d23
x3 y3 d33
How do i get an output as a matrix
x1 x2 x3
y1 d11 d21 d31
y2 d12 d22 d32
y3 d13 d23 d33
Also I want the output unsorted.

Have you looked into pivot tables? This would look like
df.pivot(index='origin', columns='Destination', values='distance')

Related

I Keep Having a Syntax Error Message With This Python Code

Having issue with small python script. trying to add 1 to a global variable every 3 iterations. I keep seeing
"for 3 in scalerVal:
^
SyntaxError: cannot assign to literal"
I will appreciate an answer
x1 = 0
x2 = 0
x3 = 0
x4 = 0
x5 = 0
x6 = 0
x7 = 0
x8 = 0
x9 = 0
itVal = 0
scalerVal = 3
# -- STEP 1: --
# (greatest value) = 3 * itVal + itVal
# adder = (greatest value) - (current value) = (differnce in value) + itVal
# scaler = itVal - intVal - itVal
# -- STEP 2: --
# add the adder to all n values
def a1():
global x1
x1 = x1 + 3
global x2
x2 = x2 + 2
global x3
x3 = x3 + 1
global x4
x4 = x4 + 2
global x5
x5 = x5 + 2
global x6
x6 = x6 + 1
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global scalerVal
for 3 in scalerVal:
scalerVal + 1
return()
global itVal
if itVal == 0:
#gVal = 3 * itVal + itVal
#adder = gVal - x1 + itVal
#x1 = x1 + adder
itVal = itVal + 1
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
else:
gVal = scalerVal * itVal + itVal
adder = gVal - x1 + itVal
x1 = x1 + adder
itVal = itVal + 1
print(x1 , x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
return()
def a2():
global x1
x1 = x1 + 2
global x2
x2 = x2 + 3
global x3
x3 = x3 + 2
global x4
x4 = x4 + 2
global x5
x5 = x5 + 2
global x6
x6 = x6 + 2
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global itVal
return()
def a3():
global x1
x1 = x1 + 1
global x2
x2 = x2 + 2
global x3
x3 = x3 + 3
global x4
x4 = x4 + 1
global x5
x5 = x5 + 2
global x6
x6 = x6 + 2
global x7
x7 = x7 + 1
global x8
x8 = x8 + 1
global x9
x9 = x9 + 1
global itVal
if itVal == 0:
#gVal = 3 * itVal + itVal
#adder = gVal - x3 + itVal
#x3 = x3 + adder
itVal = itVal + 1
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
else:
gVal = 3 * itVal + itVal
adder = gVal - x3 + itVal
x3 = x3 + adder
itVal = itVal + 1
print(x1 , x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
return()
def valAdd():
#for _ in range(1000000000):
#a1()
a1()
a2()
a3()
print(x1, x2, x3, x4, x5, x6, x7, x8, x9, itVal)
return()
valAdd()
Having issue with small python script. trying to add 1 to a global variable every 3 iterations. I keep seeing
"for 3 in scalerVal: ^ SyntaxError: cannot assign to literal"
I will appreciate an answer
The problem is that you are using a constant where you should put a variable instead.
More specifically, in the python for loop, it should be something like this:
for x in [scalerVal]
Actually, the first one should be a variable and the second one should be a iterable
3 needs to be a variable name such as X
for x in scalerVal:
x + 1
return()
Also, scalarVal should be a list or array, not a scalar for use with for.
You can just use the value directly.

Why when using Mystic in Python to optimise a non linear constrained optimisation do I receive a 'cannot simply inequalities' error?

I am trying to optimise the problem below using Mystic. I am currently receiving an error that I don't understand and was hoping someone more familiar with the library could help.
def objective(x):
x0,x1,x2,x3,x4,x5,x6,x7,x8 = x
return x0**2 + x4**2 + x8**2
equations = '''
x0 + x1 + x2 - x3 - x6 - 20 == 0.0
x4 + x3 + x5 - x1 - x7 - 150 == 0.0
x8 + x6 + x7 - x2 - x5 + 100 == 0.0
x6 == 0
x7 == 0
x0 >= 10
x4 >= 60
'''
from mystic.symbolic import generate_conditions, generate_penalty
pf = generate_penalty(generate_conditions(equations), k=1e4)
from mystic.symbolic import generate_constraint, generate_solvers, solve
cf = generate_constraint(generate_solvers(solve(equations))
When calculating cf i receive an 'NotImplementedError:cannot simplify inequalities' and wanted to know why this could be?
If anyone knows how i would extend this such that i can create the constraints through a function or in a different manner I would also be keen to know.
Cheers
I'm the mystic author. You should always first try just using solve(equations) and see what happens. It can fail to symbolically solve the equations due to the inequalities. If so, then try to do simplify(equalities) instead. That symbolically simplifies equations so there's only one variable on the LHS for each line. The inequality solver usually can then work in that case. If that fails, you can rewrite the equations so there's only one variable on the LHS.
>>> def objective(x):
... x0,x1,x2,x3,x4,x5,x6,x7,x8 = x
... return x0**2 + x4**2 + x8**2
...
>>> import mystic
>>> equations = '''
... x0 + x1 + x2 - x3 - x6 - 20 == 0.0
... x4 + x3 + x5 - x1 - x7 - 150 == 0.0
... x8 + x6 + x7 - x2 - x5 + 100 == 0.0
... x6 == 0
... x7 == 0
... x0 >= 10
... x4 >= 60
... '''
>>> eqns = mystic.symbolic.simplify(equations)
>>> print(eqns)
x0 == -x1 - x2 + x3 + x6 + 20
x8 == x2 + x5 - x6 - x7 - 100
x4 >= 60
x7 == 0
x6 == 0
x0 >= 10
x4 == x1 - x3 - x5 + x7 + 150
>>> from mystic.symbolic import generate_constraint, generate_solvers
>>> cf = generate_constraint(generate_solvers(eqns))
>>> cf([0,1,2,3,4,5,6,7,8])
[26, 1, 2, 3, 143, 5, 0, 0, -106]
>>>

Create a new dataframe with k copies of each row appended to itself

Suppose I have a dataframe with n rows:
Index data1 data2 data3
0 x0 x0 x0
1 x1 x1 x1
2 x2 x2 x2
...
n xn xn xn
How do I create a new dataframe (using pandas) with k copies of each row appended to itself:
Index data1 data2 data3
0 x0 x0 x0
1 x0 x0 x0
...
k-1 x0 x0 x0
k x1 x1 x1
k+1 x1 x1 x1
...
2k-1 x1 x1 x1
2k x2 x2 x2
...
First concat, then sort
The method I'd use is to create a list of duplicate dataframes, concat them together, and then sort_index:
count = 5
new_df = pd.concat([df]*count).sort_index()
Using numpy.repeat and .iloc In here, k=2
df.iloc[np.repeat(np.arange(len(df)), 3)]
Out[256]:
Index data1 data2 data3
0 0 x0 x0 x0
0 0 x0 x0 x0
0 0 x0 x0 x0
1 1 x1 x1 x1
1 1 x1 x1 x1
1 1 x1 x1 x1
2 2 x2 x2 x2
2 2 x2 x2 x2
2 2 x2 x2 x2
Option 1
Use repeat + reindex + reset_index:
df
data1 data2 data3
0 x0 x0 x0
1 x1 x1 x1
2 x2 x2 x2
df.reindex(df.index.repeat(5)).reset_index(drop=1)
data1 data2 data3
0 x0 x0 x0
1 x0 x0 x0
2 x0 x0 x0
3 x0 x0 x0
4 x0 x0 x0
5 x1 x1 x1
6 x1 x1 x1
7 x1 x1 x1
8 x1 x1 x1
9 x1 x1 x1
10 x2 x2 x2
11 x2 x2 x2
12 x2 x2 x2
13 x2 x2 x2
14 x2 x2 x2
Option 2
Similar solution with repeat + pd.DataFrame:
pd.DataFrame(np.repeat(df.values, 5, axis=0), columns=df.columns)
data1 data2 data3
0 x0 x0 x0
1 x0 x0 x0
2 x0 x0 x0
3 x0 x0 x0
4 x0 x0 x0
5 x1 x1 x1
6 x1 x1 x1
7 x1 x1 x1
8 x1 x1 x1
9 x1 x1 x1
10 x2 x2 x2
11 x2 x2 x2
12 x2 x2 x2
13 x2 x2 x2
14 x2 x2 x2
Comparisons
%timeit pd.concat([df] * 100000).sort_index().reset_index(drop=1)
1 loop, best of 3: 14.6 s per loop
%timeit df.iloc[np.repeat(np.arange(len(df)), 100000)].reset_index(drop=1)
10 loops, best of 3: 22.6 ms per loop
%timeit df.reindex(df.index.repeat(100000)).reset_index(drop=1)
10 loops, best of 3: 19.9 ms per loop
%timeit pd.DataFrame(np.repeat(df.values, 100000, axis=0), columns=df.columns)
100 loops, best of 3: 17.1 ms per loop

Rearrange data in csv with Python

I have a .csv file with the following format:
A B C D E F
X1 X2 X3 X4 X5 X6
Y1 Y2 Y3 Y4 Y5 Y6
Z1 Z2 Z3 Z4 Z5 Z6
What I want:
A X1
B X2
C X3
D X4
E X5
F X6
A Y1
B Y2
C Y3
D Y4
E Y5
F Y6
A Z1
B Z2
C Z3
D Z4
E Z5
F Z6
I am unable to wrap my mind around the built-in transpose functions in order to achieve the final result. Any help would be appreciated.
You can simply melt your dataframe using pandas:
import pandas as pd
df = pd.read_csv(csv_filename)
>>> pd.melt(df)
variable value
0 A X1
1 A Y1
2 A Z1
3 B X2
4 B Y2
5 B Z2
6 C X3
7 C Y3
8 C Z3
9 D X4
10 D Y4
11 D Z4
12 E X5
13 E Y5
14 E Z5
15 F X6
16 F Y6
17 F Z6
A pure python solution would be as follows:
file_out_delimiter = ',' # Use '\t' for tab delimited.
with open(filename, 'r') as f, open(filename_out, 'w') as f_out:
headers = f.readline().split()
for row in f:
for pair in zip(headers, row.split()):
f_out.write(file_out_delimiter.join(pair) + '\n')
resulting in the following file contents:
A,X1
B,X2
C,X3
D,X4
E,X5
F,X6
A,Y1
B,Y2
C,Y3
D,Y4
E,Y5
F,Y6
A,Z1
B,Z2
C,Z3
D,Z4
E,Z5
F,Z6

Rows that appear in two separate txt files, remove from one txt file

Pretty new to python. My issue is that I have one txt file ('A.txt') that has a bunch of columns in it and a second txt file ('B.txt) that has different data. However, some of the data that's in B also shows up in A. Example:
A.txt:
name1 x1 y1
name2 x2 y2
name3 x3 y3
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
B.txt
namea xa ya
name2 x2 y2
name3 x3 y3
nameb xb yb
namec xc yc
...
I want everything in B.txt that shows up in A.txt to be removed from A.txt
I realize this has been asked before, but I have tried the advice that was given to people asking a similar question, but it doesn't work for me.
So far I have:
tot = 0
with open('B.txt', 'r') as f1:
for a in f1:
WR = a.strip().split()
with open('A.txt', 'r+') as f2:
for b in f2:
l = b.strip().split()
if WR not in l:
print l
tot += 1
#I've done it the following way and also doesn't give the
#output I need
#if WR == l: #find duplicates
# continue
#else:
# print l
print tot
When I run this I get back what I think is the answer (file A has 2060 file B has 154) but repeated 154 times.
So example of what I mean is:
A.txt:
name1 x1 y1
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
name1 x1 y1
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
name1 x1 y1
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
name1 x1 y1
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
I only want it to look like:
A.txt:
name1 x1 y1
name4 x4 y4
name5 x5 y5
name6 x6 y6
...
Like I've said, I've already looked at the other similar questions and tried what they did and it's giving me this repeating answer. Any suggestions would greatly be appreciated!
I just copied your A and B files so just check and let me know if its correct
tot = 0
f1 = open('B.txt', 'r')
f2 = open('A.txt', 'r')
lista = []
for line in f1:
line.strip()
lista.append(line)
listb = []
for line in f2:
line.strip()
listb.append(line)
for b in listb:
if b in lista:
continue
else:
print(b)
tot+=1
This code prints the line, but if you want you can write it to a file too

Categories

Resources