Separating rows of output by commas and staying in float - python

I'm having a problem because I have an output of A formatted like so:
[0.018801, 0.011839, -3332.980568, 0.009446, -3332.984916, 0.007438, -3332.982958]
[0.020493, 0.015735, -3332.980353, 0.013179, -3332.968465, 0.055135, 0.135461]
[0.020678, 0.018212, -3332.983603, 0.011993, 0.097811, 0.014364, 0.099570]
[0.020758, 0.015798, -3332.982745, 0.013539, 0.086793, 0.007399, -3332.984997]
[-3332.992594, 0.014576, -3332.979745, 0.015103, 0.089420, 0.009226, 0.090133]
however, I need each row to be separated by a comma in order for it to work in this bit of code:
def mean(a):
return sum(a) / len(a)
a = [A]
print map(mean, zip(*a))
is there any way to achieve this while still keeping A as a list of floats? because ', '.join requires string values which will not allow me to take the mean
below is the code I am using to generate A:
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A = [(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3]
Any help is appreciated
clarification:
I don't need a longer list necessarily I need the list I have to be the same but for each row to be separated by commas. so when I pass this through mean:
def mean(a):
return sum(a) / len(a)
a = [A]
print map(mean, zip(*a)
I only get the last row:
[-3332.992594, 0.014576, -3332.979745, 0.015103, 0.089420, 0.009226, 0.090133]
However if I write the output of A and separate each row by a comma like so:
def mean(a):
return sum(a) / len(a)
a = [[0.018801, 0.011839, -3332.980568, 0.009446, -3332.984916, 0.007438, -3332.982958],
[0.020493, 0.015735, -3332.980353, 0.013179, -3332.968465, 0.055135, 0.135461],
[0.020678, 0.018212, -3332.983603, 0.011993, 0.097811, 0.014364, 0.099570],
[0.020758, 0.015798, -3332.982745, 0.013539, 0.086793, 0.007399, -3332.984997],
[-3332.992594, 0.014576, -3332.979745, 0.015103, 0.089420, 0.009226, 0.090133]]
print map(mean, zip(*a))
I get the desired output of
[-666.582372, 0.015232, -3332.981403, 0.012652, -1333.1358714, 0.018713, -1333.128558]
or the mean of each column.
How can I do this without having to manually doctor the A vector with commas?

Extrapolating from your other question, I think you could do what you want with something like this:
def mean(a):
return sum(a) / len(a)
averages = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A = [(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3]
averages.append(A)
print map(mean, zip(*averages))
Alternatively it could be done a little more concisely with code similar to this:
def mean(a):
return sum(a) / len(a)
averages = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A = [mean(map(float, (a, b, c))),
mean(map(float, (d, e, f))),
mean(map(float, (g, h, i))),
mean(map(float, (j, k, l))),
mean(map(float, (m, n, o))),
mean(map(float, (p, q, r))),
mean(map(float, (s, t, u)))]
averages.append(A)
print map(mean, zip(*averages))
And even more concisely with this:
def mean(a):
return sum(a) / len(a)
averages = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
cols = row.split("\t") # split into columns
# then split that into fields
date, time, values, LZA, SZA, LAM = (cols[0], cols[1], cols[2:23],
cols[23], cols[24], cols[25])
A = [mean(map(float, values[i:i+3])) for i in xrange(0, 21, 3)]
averages.append(A)
print map(mean, zip(*averages))
In the last one you could rename averages to a if you wanted because there is no longer a field named a that would conflict with it. Regardless, all code fragments will print the same answer.

You are trying to generate a list of lists. However, you aren't saving each list -- every time you go through the loop you create a new record and then replace it with the next record. This is why a eventually just contains the last record.
The commas aren't relevant -- that's just Python's syntax. The values are not stored with commas internally!
Instead of assigning each record to A, initialize A as an empty list and then add each new record to the end.
A = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A.append([(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3])

You can transform the list of floats into a list of strings using a list comprehension:
','.join(str(f) for f in A)

Use str() to convert them to string before passing them to str.join, this won't affect the original items at all:
>>> lis = [0.018801, 0.011839, -3332.980568, 0.009446, -3332.984916, 0.007438, -3332.982958]
>>> print ", ".join(str(x) for x in lis)
0.018801, 0.011839, -3332.980568, 0.009446, -3332.984916, 0.007438, -3332.982958
List still contains floats:
>>> lis
[0.018801, 0.011839, -3332.980568, 0.009446, -3332.984916, 0.007438, -3332.982958]

Related

How to take numbers from a .txt list and save the result in another .txt?

This script has a formula where at the beginning the numbers x1 and x2 in the code are set, and
I need to change the code so that the value x1 is taken from the list
pre-prepared text document
For example, from a document: 'List.txt'
That is, it turns out I need to enter:
with open ("List.txt '", "r") as f:
into place the value x1 = 6 in the code. But how to systematize it? Just not very rich in knowledge of Python.
List of numbers:
1
4
2
15
6
8
13
3
12
5
10
7
14
9
11
Code: (Powered by Python 2.7)
import sys
a=0
b=7
p=37
x1=6
x2=8
if (len(sys.argv)>1):
x1=int(sys.argv[1])
if (len(sys.argv)>2):
x2=int(sys.argv[2])
if (len(sys.argv)>3):
p=int(sys.argv[3])
if (len(sys.argv)>4):
a=int(sys.argv[4])
if (len(sys.argv)>5):
b=int(sys.argv[5])
def modular_sqrt(a, p):
""" Find a quadratic residue (mod p) of 'a'. p
must be an odd prime.
Solve the congruence of the form:
x^2 = a (mod p)
And returns x. Note that p - x is also a root.
0 is returned is no square root exists for
these a and p.
The Tonelli-Shanks algorithm is used (except
for some simple cases in which the solution
is known from an identity). This algorithm
runs in polynomial time (unless the
generalized Riemann hypothesis is false).
"""
# Simple cases
#
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return p
elif p % 4 == 3:
return pow(a, (p + 1) / 4, p)
# Partition p-1 to s * 2^e for an odd s (i.e.
# reduce all the powers of 2 from p-1)
#
s = p - 1
e = 0
while s % 2 == 0:
s /= 2
e += 1
# Find some 'n' with a legendre symbol n|p = -1.
# Shouldn't take long.
#
n = 2
while legendre_symbol(n, p) != -1:
n += 1
x = pow(a, (s + 1) / 2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in xrange(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2 ** (r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
def legendre_symbol(a, p):
""" Compute the Legendre symbol a|p using
Euler's criterion. p is a prime, a is
relatively prime to p (if p divides
a, then a|p = 0)
Returns 1 if a has a square root modulo
p, -1 otherwise.
"""
ls = pow(a, (p - 1) / 2, p)
return -1 if ls == p - 1 else ls
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
print ("x")
else:
return x % m
print "a=",a
print "b=",b
print "p=",p
print "x-point=",x1
print "x-point=",x2
z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)
z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)
print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)
s=((-y2)-y1)* modinv(x2-x1,p)
x3=(s**2-x2-x1) % p
y3=((s*(x2-x3)+y2)) % p
result = "Q\t(%d,%d)" % (x3,y3)
f = open('Result01.txt', 'w')
f.write(result)
f.close()
Earlier, I saw scripts where numbers are taken from one text document, perform a function, and the result is saved in another text document.
Try using the pandas library to read, process and write your numbers.
import pandas as pd # import pandas module and call it pd for short
x2 = 6
df = pd.read_csv('input_file.txt') # read the data from a text file into a dataframe
df['x1 times x2'] = df['x1'] * x2 # create new column in your dataframe with result of your function
df.to_csv('output_file.txt', index=False) # output result of your calculations (dropping the dataframe index column)
Although you're hard coding the values of x1, x2, in your code, they can be redefined, as you're doing here:
if (len(sys.argv)>1):
x1=int(sys.argv[1])
if (len(sys.argv)>2):
x2=int(sys.argv[2])
So if you call your script from command line, like C:\Users\test.py x1value x2value you can redefine x1 and x2. If you really want a text file to contain your x1 and x2, just use the following snippet somewhere at the top
import json
with open("input.json","r",encoding="utf-8") as stream:
parsed = json.load(stream)
x1,x2 = parsed["x1"],parsed["x2"]
Contents of "input.json":
{"x1":1,"x2"=2}
With only python without extra dependencies, your can read List.txt as follow
with open("List.txt","r") as f:
arrX1 = list(map(int,f.readlines()))
print (arrX1)
The above reads all the lines in f and converts/maps them to integers. The list function then gives you an array you can loop through to generate x2 and write to the Result.txt file.
The above prints
[1, 4, 2, 15, 6, 8, 13, 5, 3, 10, 7, 14, 9, 11]
So for your code replace all lines from 125 downward with
# Read numbers from file and put them in an array
with open("List.txt","r") as f:
arrX1 = list(map(int,f.readlines()))
f.close()
# Open the result file to write to
f = open('Result01.txt', 'w')
# Now get x1 for each item in the list of numbers from the file
# then do the calculations
# and write the result
for x1 in arrX1:
z=(x1**3 + a*x1 +b) % p
y1=modular_sqrt(z, p)
z=(x2**3 + a*x2 +b) % p
y2=modular_sqrt(z, p)
print "\nP1\t(%d,%d)" % (x1,y1)
print "P2\t(%d,%d)" % (x2,y2)
s=((-y2)-y1)* modinv(x2-x1,p)
x3=(s**2-x2-x1) % p
y3=((s*(x2-x3)+y2)) % p
result = "Q\t(%d,%d)" % (x3,y3)
f.write(result)
f.close()

How can I find string variations in dictionary within a distance of 1?

Say you have scanned a document with names on it. Due to mistakes in the scanning process, you want to look up the names in a dictionary. Therefore, you need a function that takes in a possible name and outputs a list with every possible string variation of the input within a Levenshtein-Distance of 1.
I modified an implementation (https://rosettacode.org/wiki/Levenshtein_distance#Python) but didn't get the right result, yet. Since Levenshtein implementations usually take in two strings and compare them to give out an int for the L-Distance, I am wondering how to change that to get the variations of one string?
def levenshteinVariation(n_possible):
m = n_possible
n = n_correct
d = []
for i in range(len(m)+1):
d.append([i])
del d[0][0]
for j in range(len(n)+1):
d[0].append(j)
for j in range(1,len(n)+1):
for i in range(1,len(m)+1):
if m[i-1] == n[j-1]:
d[i].insert(j,d[i-1][j-1])
else:
minimum = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+2)
d[i].insert(j, minimum)
return d
The expected result would be a match in the dictionary to all variations within a L-Distance of 1.
for n_correct, n_possible in [('Marcus','Maacus'), ('David','Davide'), ('Steve', 'Steven')]:
print(f"{n_correct} found: {n_correct in levenshteinVariation(n_possible)}")
But I got:
Marcus found: False
David found: False
Steve found: False
Thanks to Dan D. I was able to solve it myself:
def Variations1(name):
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
splits = [(name[:i], name[i:]) for i in range(len(name) + 1)]
deletes = [L + R[1:] for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1]
replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
inserts = [L + c + R for L, R in splits for c in letters]
return set(deletes + transposes + replaces + inserts)

Printing list items along with index

Suppose I have a list a = [x, y, z], and I want to print
1. x
2. y
3. z
I can do it, but it is a bit lengthy, like
c = 1
for i in a:
print(str(c) + "." + i)
c += 1
Is there a shorter way of doing it? Any help is appreciated. Thanks in advance.
What about this example, where i is the index and e would be each item from a list.
for i,e in enumerate(a):
print (str(i + 1) + '.', e)
As #niemmi suggests, you could also start the index at 1:
for i,e in enumerate(a, start=1):
print (str(i) + '.', e)

Too many values to unpack or 0 values to unpack

I have this code and I am trying to use the list splits
but either I get Too many values to unpack or need more than 0 values to unpack
def edits1(word):
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
temp1 = []
for i in splits:
temp = list(i)
for j in range(0,len(temp)):
temp1.append(temp[j])
splits = temp1
for s in splits:
print s
#here
deletes = [a + b[1:] for a, b in splits if b]
return set(deletes)

Screening out negatives before taking average

I have this program to read in data, average across a row of three and then average down columns, so far it does all this fine. However I am now trying to go back and have it take out negative data points and I'm having some trouble:
from __future__ import division
import csv
v = open("Pt_2_Test_Data.csv", 'wb') #created file to write output to
A =[]
B = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A.append([(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3])
def mean(B):
return sum(B) / len(B)
for x in A:
if x > 0:
B.append(x)
print B
C = map(mean, zip(*B))
print C
v.close()
(I'm not worried about writing the data to the file yet, just getting rid of the negatives before the final average is taken.)
I'm not sure this is what you mean, but you can make a change to your mean function like so:
def mean(B):
positives = [b for b in B if b >= 0]
return sum(positives) / len(positives)
This will give you the average of the non-negative members of B. Is this kind of what you were looking for?
In general, that comprehension is one way to get the non-negative members of a list. Another way, which makes more sense to me, is
filter (lambda i: i >=0, some_list)
This seems to be undergoing some deprecation, though.

Categories

Resources