简体   繁体   中英

Print two arrays side by side using numpy

I'm trying to create a table of cosines using numpy in python. I want to have the angle next to the cosine of the angle, so it looks something like this:

0.0    1.000  5.0    0.996  10.0    0.985  15.0 0.966
20.0   0.940  25.0   0.906 and so on. 

I'm trying to do it using a for loop but I'm not sure how to get this to work. Currently, I have.

Any suggestions?

Let's say you have:

>>> d = np.linspace(0, 360, 10, endpoint=False)
>>> c = np.cos(np.radians(d))

If you don't mind having some brackets and such on the side, then you can simply concatenate column-wise using np.c_ , and display:

>>> print(np.c_[d, c])
[[  0.00000000e+00   1.00000000e+00]
 [  3.60000000e+01   8.09016994e-01]
 [  7.20000000e+01   3.09016994e-01]
 [  1.08000000e+02  -3.09016994e-01]
 [  1.44000000e+02  -8.09016994e-01]
 [  1.80000000e+02  -1.00000000e+00]
 [  2.16000000e+02  -8.09016994e-01]
 [  2.52000000e+02  -3.09016994e-01]
 [  2.88000000e+02   3.09016994e-01]
 [  3.24000000e+02   8.09016994e-01]]

But if you care about removing them, one possibility is to use a simple regex:

>>> import re
>>> print(re.sub(r' *\n *', '\n',
                 np.array_str(np.c_[d, c]).replace('[', '').replace(']', '').strip()))
0.00000000e+00   1.00000000e+00
3.60000000e+01   8.09016994e-01
7.20000000e+01   3.09016994e-01
1.08000000e+02  -3.09016994e-01
1.44000000e+02  -8.09016994e-01
1.80000000e+02  -1.00000000e+00
2.16000000e+02  -8.09016994e-01
2.52000000e+02  -3.09016994e-01
2.88000000e+02   3.09016994e-01
3.24000000e+02   8.09016994e-01

I'm removing the brackets, and then passing it to the regex to remove the spaces on either side in each line.

np.array_str also lets you set the precision. For more control, you can use np.array2string instead.

You can use python's zip function to go through the elements of both lists simultaneously.

import numpy as np
degreesVector = np.linspace(0.0, 360.0, 73.0)
cosinesVector = np.cos(np.radians(degreesVector))
for d, c in zip(degreesVector, cosinesVector):
    print d, c

And if you want to make a numpy array out of the degrees and cosine values, you can modify the for loop in this way:

table = []
for d, c in zip(degreesVector, cosinesVector):
    table.append([d, c])
table = np.array(table)

And now on one line!

np.array([[d, c] for d, c in zip(degreesVector, cosinesVector)])

Pandas is very convenient module for such tasks:

In [174]: import pandas as pd
     ...:
     ...: x = pd.DataFrame({'angle': np.linspace(0, 355, 355//5+1),
     ...:                   'cos': np.cos(np.deg2rad(np.linspace(0, 355, 355//5+1)))})
     ...:
     ...: pd.options.display.max_rows = 20
     ...:
     ...: x
     ...:
Out[174]:
    angle       cos
0     0.0  1.000000
1     5.0  0.996195
2    10.0  0.984808
3    15.0  0.965926
4    20.0  0.939693
5    25.0  0.906308
6    30.0  0.866025
7    35.0  0.819152
8    40.0  0.766044
9    45.0  0.707107
..    ...       ...
62  310.0  0.642788
63  315.0  0.707107
64  320.0  0.766044
65  325.0  0.819152
66  330.0  0.866025
67  335.0  0.906308
68  340.0  0.939693
69  345.0  0.965926
70  350.0  0.984808
71  355.0  0.996195

[72 rows x 2 columns]

Side-by-Side Array Comparison using Numpy

A built-in Numpy approach using the column_stack((...)) method.

numpy.column_stack((A, B)) is a column stack with Numpy which allows you to compare two or more matrices/arrays.

Use the numpy.column_stack((A, B)) method with a tuple. The tuple must be represented with () parenthesizes representing a single argument with as many matrices/arrays as you want .

import numpy as np

A = np.random.uniform(size=(10,1))
B = np.random.uniform(size=(10,1))
C = np.random.uniform(size=(10,1))

np.column_stack((A, B, C)) ## <-- Compare Side-by-Side

The result looks like this:

array([[0.40323596, 0.95947336, 0.21354263],
       [0.18001121, 0.35467198, 0.47653884],
       [0.12756083, 0.24272134, 0.97832504],
       [0.95769626, 0.33855075, 0.76510239],
       [0.45280595, 0.33575171, 0.74295859],
       [0.87895151, 0.43396391, 0.27123183],
       [0.17721346, 0.06578044, 0.53619146],
       [0.71395251, 0.03525021, 0.01544952],
       [0.19048783, 0.16578012, 0.69430883],
       [0.08897691, 0.41104408, 0.58484384]])

Numpy column_stack is useful for AI/ML applications when comparing the predicted results with the expected answers. This determines the effectiveness of the Neural Net training. It is a quick way to detect where errors are in the network calculations.

You were close - but if you iterate over angles, just generate the cosine for that angle:

In [293]: for angle in range(0,60,10):
     ...:     print('{0:8}{1:8.3f}'.format(angle, np.cos(np.radians(angle))))
     ...:     
       0   1.000
      10   0.985
      20   0.940
      30   0.866
      40   0.766
      50   0.643

To work with arrays, you have lots of options:

In [294]: angles=np.linspace(0,60,7)
In [295]: cosines=np.cos(np.radians(angles))

iterate over an index:

In [297]: for i in range(angles.shape[0]):
     ...:     print('{0:8}{1:8.3f}'.format(angles[i],cosines[i]))

Use zip to dish out the values 2 by 2:

for a,c in zip(angles, cosines):
    print('{0:8}{1:8.3f}'.format(a,c))

A slight variant on that:

for ac in zip(angles, cosines):
     print('{0:8}{1:8.3f}'.format(*ac))

You could concatenate the arrays together into a 2d array, and display that:

In [302]: np.vstack((angles, cosines)).T
Out[302]: 
array([[  0.        ,   1.        ],
       [ 10.        ,   0.98480775],
       [ 20.        ,   0.93969262],
       [ 30.        ,   0.8660254 ],
       [ 40.        ,   0.76604444],
       [ 50.        ,   0.64278761],
       [ 60.        ,   0.5       ]])

In [318]: print(np.vstack((angles, cosines)).T)
[[  0.           1.        ]
 [ 10.           0.98480775]
 [ 20.           0.93969262]
 [ 30.           0.8660254 ]
 [ 40.           0.76604444]
 [ 50.           0.64278761]
 [ 60.           0.5       ]]

np.column_stack can do that without the transpose.

And you can pass that array to your formatting with:

for ac in np.vstack((angles, cosines)).T:
    print('{0:8}{1:8.3f}'.format(*ac))

or you could write that to a csv style file with savetxt (which just iterates over the 'rows' of the 2d array and writes with fmt ):

In [310]: np.savetxt('test.txt', np.vstack((angles, cosines)).T, fmt='%8.1f  %8.3f')
In [311]: cat test.txt
     0.0     1.000
    10.0     0.985
    20.0     0.940
    30.0     0.866
    40.0     0.766
    50.0     0.643
    60.0     0.500

Unfortunately savetxt requires the old style formatting. And trying to write to sys.stdout runs into byte v unicode string issues in Py3.

Just in numpy with some format ideas, to use @MaxU 's syntax

a = np.array([[i, np.cos(np.deg2rad(i)), np.sin(np.deg2rad(i))]
               for i in range(0,361,30)])
args = ["Angle", "Cos", "Sin"]
frmt = ("{:>8.0f}"+"{:>8.3f}"*2)
print(("{:^8}"*3).format(*args))
for i in a:
    print(frmt.format(*i))
 Angle    Cos     Sin   
       0   1.000   0.000
      30   0.866   0.500
      60   0.500   0.866
      90   0.000   1.000
     120  -0.500   0.866
     150  -0.866   0.500
     180  -1.000   0.000
     210  -0.866  -0.500
     240  -0.500  -0.866
     270  -0.000  -1.000
     300   0.500  -0.866
     330   0.866  -0.500
     360   1.000  -0.000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM