Nethanel Benzak
Nethanel Benzak

Reputation: 21

Converting multidimensional array to tuple while conserving format- python

I'm trying to the convert a multidimensional array with different formats to a tuple all while conserving the different formats. Here is the code that builds the array

nodeData=np.empty((npoints*npoints,4))
ii=0
for i in range (npoints):
    for j in range (npoints):
        nodeData[ii,0]=int(ii+1)
        nodeData[ii,1]=float(X[i,j])
        nodeData[ii,2]=float(Y[i,j])
        nodeData[ii,3]=float(Z[i,j])
        ii+=1

which outputs

[[  1.          10.           2.           0.        ]
 [  2.           9.23463314   1.84775906   0.        ]
 [  3.           8.58578682   1.41421354   0.        ]
 [  4.           8.15224103   0.76536686   0.        ]
 [  5.           8.           0.           0.        ]
 [  6.          10.           4.           0.        ]
 [  7.           8.14486726   3.94570562   0.        ]
 [  8.           6.43933982   3.56066012   0.        ]
 [  9.           6.05429438   1.8551327    0.        ]
 [ 10.           6.           0.           0.        ]
 [ 11.          10.           6.           0.        ]
 [ 12.           7.07624214   6.00295346   0.        ]
 [ 13.           4.29289317   5.70710671   0.        ]
 [ 14.           3.99704657   2.92375783   0.        ]
 [ 15.           4.           0.           0.        ]
 [ 16.          10.           8.           0.        ]
 [ 17.           6.02814844   8.02067549   0.        ]
 [ 18.           2.14644665   7.85355332   0.        ]
 [ 19.           1.97932457   3.97185155   0.        ]
 [ 20.           2.           0.           0.        ]
 [ 21.          10.          10.           0.        ]
 [ 22.           5.          10.           0.        ]
 [ 23.           0.          10.           0.        ]
 [ 24.           0.           5.           0.        ]
 [ 25.           0.           0.           0.        ]]

Now when I try to convert this to a tuple using nodeData = tuple(map(tuple, nodeData)) I obtain

((1.0, 10.0, 2.0, 0.0), (2.0, 9.234633143257458, 1.847759058732358, 0.0), (3.0, 8.5857868194580078, 1.4142135381698608, 0.0), (4.0, 8.1522410342120963, 0.76536686381751795, 0.0), (5.0, 8.0, 0.0, 0.0), (6.0, 10.0, 4.0, 0.0), (7.0, 8.144867260307727, 3.9457056195410947, 0.0), (8.0, 6.439339816570282, 3.5606601238250732, 0.0), (9.0, 6.0542943801670015, 1.8551327030961533, 0.0), (10.0, 6.0, 0.0, 0.0), (11.0, 10.0, 6.0, 0.0), (12.0, 7.0762421416553485, 6.0029534580819224, 0.0), (13.0, 4.2928931713104248, 5.7071067094802856, 0.0), (14.0, 3.997046571142258, 2.9237578279641867, 0.0), (15.0, 4.0, 0.0, 0.0), (16.0, 10.0, 8.0, 0.0), (17.0, 6.028148440014629, 8.0206754926510051, 0.0), (18.0, 2.1464466452598572, 7.8535533249378204, 0.0), (19.0, 1.9793245736169094, 3.9718515524632179, 0.0), (20.0, 2.0, 0.0, 0.0), (21.0, 10.0, 10.0, 0.0), (22.0, 5.0, 10.0, 0.0), (23.0, 0.0, 10.0, 0.0), (24.0, 0.0, 5.0, 0.0), (25.0, 0.0, 0.0, 0.0))

It has converted all the values to floats when I'm trying to conserve the first value of each row as an interger as such:

((1, 10.0, 2.0, 0.0),
 (2, 9.234633143257458, 1.847759058732358, 0.0), 
(3, 8.5857868194580078, 1.4142135381698608, 0.0), 
(4, 8.1522410342120963, 0.76536686381751795, 0.0), 
(5, 8.0, 0.0, 0.0), 
(6, 10.0, 4.0, 0.0), 
(7, 8.144867260307727, 3.9457056195410947, 0.0), 
(8, 6.439339816570282, 3.5606601238250732, 0.0), 
(9, 6.0542943801670015, 1.8551327030961533, 0.0), 
(10, 6.0, 0.0, 0.0), 
(11, 10.0, 6.0, 0.0), 
(12, 7.0762421416553485, 6.0029534580819224, 0.0), 
(13, 4.2928931713104248, 5.7071067094802856, 0.0), 
(14, 3.997046571142258, 2.9237578279641867, 0.0), 
(15, 4.0, 0.0, 0.0), 
(16, 10.0, 8.0, 0.0), 
(17, 6.028148440014629, 8.0206754926510051, 0.0), 
(18, 2.1464466452598572, 7.8535533249378204, 0.0), 
(19, 1.9793245736169094, 3.9718515524632179, 0.0), 
(20, 2.0, 0.0, 0.0), 
(21, 10.0, 10.0, 0.0), 
(22, 5.0, 10.0, 0.0), 
(23, 0.0, 10.0, 0.0), 
(24, 0.0, 5.0, 0.0), 
(25, 0.0, 0.0, 0.0))

Alternatively is there anyway to get the final result without building the array, rather building the tuple directly in the correct format? Any help would be greatly appreciated.

Upvotes: 0

Views: 80

Answers (3)

H. Ross
H. Ross

Reputation: 540

As an alternative to Barmar's answer, you could also use a generator:

def generate():
    for i in range(npoints):
        for j in range(npoints):
            yield (int(ii+1), float(X[i,j]), float(Y[i,j]), float(Z[i,j]))
            ii += 1

nodeData = tuple(generate())

Upvotes: 0

grey_ranger
grey_ranger

Reputation: 1030

When you first create the nodeData array, you can check the dtype and notice that the array is of type float64 (see print statement below):

npoints = 25
nodeData=np.empty((npoints*npoints,4))
print(nodeData.dtype)

'float64'

This means that when you're assigning the integer later, it's automatically converted to a float (see print statement below):

npoints = 25
nodeData=np.empty((npoints*npoints,4))
ii=0
for i in range (npoints):
    for j in range (npoints):
        nodeData[ii,0]=int(ii+1)
        print(nodeData[ii,0].dtype)

'float64'...

As @barmar suggests, you'll have to build a set of tuples in a way that doesn't cast your integer value to float (the way that setting a value in the numpy array will auto-cast to match the array type).

Upvotes: 1

Barmar
Barmar

Reputation: 781068

You can't build a tuple incrementally, because tuples are immutable. But you can build a list and then convert it to a tuple.

nodeData = []
ii = 1
for i in range (npoints):
    for j in range (npoints):
        nodeData.append((ii, float(X[i,j]), float(Y[i,j]), float(Z[i,j])))
        ii += 1
nodeData = tuple(nodeData)

Upvotes: 1

Related Questions