0

I have done the following code:

test.py

nc = 1; nb = 20; ni = 6; nc = 2; ia = 20; ib = 20; ic = 0

U1 = numpy.array((1,2,0,0,0,3))
U2 = numpy.array((2,2,1,0,0,1))
U3 = numpy.array((2,1,1,0,0,2))
U4 = numpy.array((2,1,0,1,0,2))
U5 = numpy.array((2,1,1,1,0,3))

for n in range(ni):
    a = nc*(nb*nc*ia+nc*ib+ic)+U1[n]
    a2 = ia + U1[n]
    b2 = ib + U3[n]
    c2 = ic + U4[n]
    b = nc*(nb*nc*a2+nc*b2+c2)+U2[n]
    A = str(numpy.array((a,b,U5[n])))
    print(A)
    with open("test.txt", 'w') as out:
        for o in A:
            out.write(o)

test.txt gives me the following:

[1683 1933    3]

But if I print test.py by using print(A), I get this:

[1681 1774    2]
[1682 1848    1]
[1680 1685    1]
[1680 1682    1]
[1680 1680    0]
[1683 1933    3]

How can I write the the whole print in test.txt? I assume to do something like this:

ol = []
ol.append(o))

3 Answers 3

2

The basic problem is you are opening the same file again and again and overwriting this file for every iteration in the for loop.

Use:

with open("test.txt", 'w') as out:
    for n in range(ni):
        a = nc*(nb*nc*ia+nc*ib+ic)+U1[n]
        a2 = ia + U1[n]
        b2 = ib + U3[n]
        c2 = ic + U4[n]
        b = nc*(nb*nc*a2+nc*b2+c2)+U2[n]
        A = str(numpy.array((a,b,U5[n])))
        out.write(f"{A}\n")

Now the text.txt file will contain:

[1681 1774    2]
[1682 1848    1]
[1680 1685    1]
[1680 1682    1]
[1680 1680    0]
[1683 1933    3]
Sign up to request clarification or add additional context in comments.

4 Comments

gives out an SyntaxError: invalid syntax
Guessing: One needs python 3.6 or newer for the f-strings.
I think your are using python 2+ so use out.write(A + "\n") instead of out.write(f"{A}\n")
You should also consider my solution because it is more portable (using a numpy lib feature) + it removes this useless loop that impacts performances.
0

The best solution - Fast and efficient

import numpy

nc = 1; nb = 20; ni = 6; nc = 2; ia = 20; ib = 20; ic = 0

U1 = numpy.array((1,2,0,0,0,3))
U2 = numpy.array((2,2,1,0,0,1))
U3 = numpy.array((2,1,1,0,0,2))
U4 = numpy.array((2,1,0,1,0,2))
U5 = numpy.array((2,1,1,1,0,3))

# No for loop here, we are using NumPy broadcasting features
a = nc*(nb*nc*ia+nc*ib+ic)+U1
a2 = ia + U1
b2 = ib + U3
c2 = ic + U4
b = nc * (nb * nc * a2 + nc * b2 + c2) + U2
# Transpose the matrix to get the result wanted in your case
A = numpy.array((a, b, U5)).T

with open(file="res.txt", mode="w") as b:
    b.write(numpy.array2string(A))

Remarks about your code written in the question

  • In most cases, using NumPy broadcasting (removing loop over arrays) makes the code faster. It can also be easier to read.
  • Writing into a file while inside a loop is a bad practice. Even if you keep your file open with the use of the context manager with open, performances are poor.
  • Better build your array, convert it to string.
  • Then write the whole thing into a file.

Other solution using numpy builtin functions

Disclaimer: To use only if the row number of your array is small (<500)

  • Dumping a numpy array into a text file is a builtin function in NumPy.

  • Look at this: API doc | numpy.savetxt

  • However, if you look at the source code of this function, you will see that you iterate over the array's rows which impacts performances a lot when dimensions number increases (thanks to @hpaulj for the remark).

  • In your case, you could replace the two last lines of the snippet above with:

numpy.savetxt("a.txt", A) # just see the doc to add some formatting options

2 Comments

savetxt takes the slow approach. It iterates on the rows of A, formatting and writing each separately.
Hi, this is an excellent remark! I was providing a solution for the case presented in the question (small arrays). In fact, savetxt slowness is barely noticable for arrays dimensions < 500 rows . I will change my answer anyway. I also provide a quick bench snippet here: gist.github.com/rjodon/2f05a60825f9bf885faf359be66d9a73
0

In each iteration of the outer loop, you are asking the file system for a fresh, empty copy of "test.txt". So of course the final version only contains the content of the last loop.

Open with the attributes "a" for "(write-and-)append" or as in the other answer, and more efficiently, open once outside of the loop.

4 Comments

so only by writing: with open("test.txt", 'wa') as out: it should work?
Try it out, there might still be the line breaks missing. Did it myself, only one attribute allowed, open("test.txt", 'a') works, without linebreaks. Add them in the construction of the string.
If you want to get only the output of one run of the script, you also need to delete the file or create anew once. Else you only ever append.
is it possible to row these array in one column?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.