I have my geographical coordinates of rectangles represented as numpy ndarray like this:
(each row corresponds to a rectangle and each column contains its lower left and upper right longitudes and latitudes)
array([
[ 116.17265886, 39.92265886, 116.1761427 , 39.92536232],
[ 116.20749721, 39.90373467, 116.21098105, 39.90643813],
[ 116.21794872, 39.90373467, 116.22143255, 39.90643813]])
I want to call a coordinate-converting API whose input is a string like this:
'lon_0,lat_0;lon_1,lat_1;lon_2,lat_2;...;lon_n,lat_n'
So I wrote a stupid iteration to convert my ndarray to the required string like this:
coords = ''
for i in range(0, my_rectangle.shape[0]):
coords = coords + '{left_lon},{left_lat};{right_lon},{rigth_lat}'.format(left_lon = my_rectangle[i][0], left_lat = my_rectangle[i][1], \
right_lon = my_rectangle[i][2], rigth_lat = my_rectangle[i][3])
if i != my_rectangle.shape[0] - 1:
coords = coords + ';'
And the output is like this:
'116.172658863,39.9226588629;116.176142698,39.9253623188;116.207497213,39.9037346711;116.210981048,39.9064381271;116.217948718,39.9037346711;116.221432553,39.9064381271'
I'm wondering whether there exists a smarter & faster approach achieving this without iteration(or some helpful documentation I could refer to)?
Let's try using functional style:
values = [[ 116.17265886, 39.92265886, 116.1761427 , 39.92536232],
[ 116.20749721, 39.90373467, 116.21098105, 39.90643813],
[ 116.21794872, 39.90373467, 116.22143255, 39.90643813]]
def prettyPrint(coords):
return '{0},{1};{2},{3}'.format(coords[0], coords[1], coords[2], coords[3])
asString = formating(list(map(prettyPrint,values)))
print(";".join(asString)) #edited thanks to comments
map apply a function to each element of an iterable. So you define the process to apply on one element, and then using map replace each element by its result.
Hope you find it smarter ;)
Edit :
You can also write it like this :
asString = [prettyPrint(value) for value in values]
Related
I would like to store generate results from a function that I created called "surface_coverage". The function returns result in numpy.ndarray form and I tried to store it into a dataframe but I kept getting error msg "Must pass 2-d input"
here is my code
T = [400,500,600,700]
result = []
for t in df_G['Temperature']:
for i in T:
columns = f'G_ads_{i}'
G_CO2 = df.loc[df.Metal_Oxides == "Al2O3"].loc[df.Adsorbates == 'CO2'][columns].min()
G_H2O = df.loc[df.Metal_Oxides == "Al2O3"].loc[df.Adsorbates == 'H2O'][columns].min()
G_O2 = df.loc[df.Metal_Oxides == "Al2O3"].loc[df.Adsorbates == 'O2'][columns].min()
if t == i+273.15:
theta = surface_coverage(t,P,G_CO2,G_H2O,G_O2,x_co2,x_h2o,x_o2)
result.append(theta)
new_data = pd.DataFrame(result)
and here is the output:
[array([[8.53931326e-04],
[9.34890812e-15],
[9.99146054e-01],
[1.46447007e-08]]), array([[1.07403011e-01],
[4.44545478e-13],
[8.92596825e-01],
[1.64041799e-07]]), array([[8.52759436e-01],
[1.52248154e-12],
[1.47240375e-01],
[1.88472871e-07]]), array([[9.92480337e-01],
[8.43223552e-13],
[7.51961814e-03],
[4.46422474e-08]]), array([[9.99428328e-01],
[4.36060531e-13],
[5.71659951e-04],
[1.17418613e-08]]), array([[9.99935140e-01],
[2.38117323e-13],
[6.48560836e-05],
[3.70506323e-09]])]
Is there any method to convert numpy.bdarray into float?
Thank you for your time and your help!
I think the issue here is that your output array is nested in a way that looks 3D rather than 2D, which is what the pandas DataFrame is looking for.
It looks like theta, the output of your surface_coverage function, is a matrix. While you might be interpreting it is as a list of 4 numbers (a vector), it looks like it is being treated as a matrix (1 row x 4 columns, which we can see by counting the brackets).
array([[8.53931326e-04],
[9.34890812e-15],
[9.99146054e-01],
[1.46447007e-08]])
You probably want this array to look like this (note the brackets):
array([8.53931326e-04,
9.34890812e-15,
9.99146054e-01,
1.46447007e-08])
To fix this, you should be able to replace
result.append(theta)
with
result.append(theta.flatten())
That'll turn these into just arrays. Your result will therefore just be a list of arrays which it should correctly identify as 2D.
a:
[array([[0.10865657, 0.10638294, 0.10471012, 0.09508586, 0.09283491],
[0.10892282, 0.10664408, 0.10496752, 0.09531553, 0.09305617],
[0.11664 , 0.1143077 , 0.11259081, 0.1026154 , 0.10025029],
[0.11626453, 0.11392252, 0.11219875, 0.10217754, 0.09980005]]),
array([[0.04213751, 0.04178241, 0.04158858, 0.04331489, 0.04447674],
[0.04213751, 0.04178241, 0.04158858, 0.04331489, 0.04447674],
[0.04267657, 0.04255925, 0.04253528, 0.04520177, 0.04655534],
...
I can do a[0].mean and I will get desired result. By I want to do it to the whole length of the 'a' with for loop.
I have tried:
mean_all = []
for i in len(dist):
mean = dist[i].mean
mean_all.append(mean)
TypeError: 'int' object is not iterable
First of all, dist[0].mean returns a function and NOT the mean. You need, in general, dist[0].mean().
You can avoid the for loop easily using list comprehension:
from numpy import array
dist = [array([[0.10865657, 0.10638294, 0.10471012, 0.09508586, 0.09283491],
[0.10892282, 0.10664408, 0.10496752, 0.09531553, 0.09305617],
[0.11664 , 0.1143077 , 0.11259081, 0.1026154 , 0.10025029],
[0.11626453, 0.11392252, 0.11219875, 0.10217754, 0.09980005]]),
array([[0.04213751, 0.04178241, 0.04158858, 0.04331489, 0.04447674],
[0.04213751, 0.04178241, 0.04158858, 0.04331489, 0.04447674],
[0.04267657, 0.04255925, 0.04253528, 0.04520177, 0.04655534]])]
mean_all = [dist[i].mean() for i in range(len(dist))]
print(mean_all)
[0.10536720549999998, 0.04307523133333334]
If you really want to use the for loop, use this:
mean_all = []
for i in range(len(dist)):
mean = dist[i].mean()
mean_all.append(mean)
print(mean_all)
[0.10536720549999998, 0.04307523133333334]
Use the correct format of using range()
for i in range(len(dist))
My data is as follows:
mx_ranges1 = [
(848,888),
(806,848),
(764,806),
(722,764),
(680,722),
(638,680),
(596,638),
(554,596),
(512,554),
(470,512),
(428,470),
(386,428),
(344,386),
(302,344),
(260,302),
(218,260),
(176,218),
(134,176),
]
a=((mx_ranges1[0][1]-mx_ranges1[0][0])/2)+(mx_ranges1[0][0])
b=((mx_ranges1[1][1]-mx_ranges1[1][0])/2)+(mx_ranges1[1][0])
c=((mx_ranges1[2][1]-mx_ranges1[2][0])/2)+(mx_ranges1[3][0])
print(a)
print(b)
print(c)`
That way is not really efficient, I know it can somehow be represented in a for loop, I just don't know how I might do it. Please give me some references since I'm new to python and programming in general. I then have another list with y which also need to take the distance then add it to the first element.
Not sure if it can be placed directly into a single 2D array but just doing the first part should be good enough for me. I can do the rest manually.
You can use a simple list comprehension:
[(j-i)/2 + i for i,j in mx_ranges1]
# [868.0, 827.0, 785.0, 743.0, 701.0, 659.0, 617.0 ...
Which is equivalent to the following for loop:
res = []
for i,j in mx_ranges1:
res.append((j-i)/2 + i)
You also mention using numpy arrays. Note that this would be the most efficient and simple way to do it, as it is a matter of Basic Slicing and Indexing:
a = np.array(mx_ranges1)
(a[:,1] - a[:,0]) /2 + a[:,0]
# array([868., 827., 785., 743., ...
Numpy will be much faster!
import numpy as np
mx_ranges1 = [
(848,888),
(806,848),
(764,806),
(722,764),
(680,722),
(638,680),
(596,638),
(554,596),
(512,554),
(470,512),
(428,470),
(386,428),
(344,386),
(302,344),
(260,302),
(218,260),
(176,218),
(134,176),
]
a = np.array(mx_ranges1)
# the first index accessor : says all rows, the second specifies a column
result = (a[:,1] - a[:,0])/2 + a[:,0]
# result contains one value for each row/tuple in `mx_ranges1`
print(result)
This returns:
[868. 827. 785. 743. 701. 659. 617. 575. 533. 491. 449. 407. 365. 323.
281. 239. 197. 155.]
Which contains one value for each row of your input 2D array. So 868 = 888-848/2 + 848.
Thanks for taking a moment to read this! So, my first issue is that I'm trying to create a function, "selectionData()", to get an object's translate, rotate, and scale values and then return them as a dictionary, but find myself struggling a bit. Using the code listed below, all I keep getting is the object's name. How can I modify it to get its translate, rotate, and scale values to return as a dictionary?
My second issue is that I'm trying to create a function, "setData(data)", that takes as input the aforementioned dictionary built with selectionData() and restores the data in the dictionary to the selected objects. How do I do that?
My apologies if either of these questions are foolish, but thank you for your time, regardless! Cheers!
Current code is listed below:
from maya import cmds
sel = cmds.ls(sl = 1)
meshes =[]
for s in sel :
shape = cmds.listRelatives(s , shapes = 1 )
if shape :
if cmds.nodeType(shape[0]) == "mesh" :
meshes.append(s )
meshData = {}
for m in meshes :
pos = cmds.xform ( m , q =1 , ws = 1 , t = 1)
rot = cmds.xform( m , q =1 , ws = 1 , rotation = 1 )
scl = cmds.getAttr ( m + '.s' )[0]
currentDict = {
"pos" : pos ,
"rot" : rot ,
"scl" : scl ,
}
meshData[m] = currentDict
def selectionData( selectionDict):
for k in selectionDict :
print k
selectionData(meshData)
First of all, to list all the objects with transforms you can use this command:
cmds.ls(selection=True, transforms=True, dagObjects=True)
If you want to read/write the transforms, you don't need to get the translation, then rotation and scale separately. You can read the composite transformation matrix like this:
xform_matrix = cmds.xform(source_object, query=True, matrix=True)
You'll get a list of 16 float numbers that are ready to be applied to other objects:
cmds.xform(destination_object, matrix=xform_matrix)
I am not sure how do you want to map the transforms from one set of selected objects to another set. If you describe, I'll be able to post the complete code.
The following script will collect the composite transformation matrix of all selected objects in the dictionary with long object names as the keys:
selected_objects_matrix = {}
for current_object in cmds.ls(selection=True, transforms=True, dagObjects=True):
selected_objects_matrix[cmds.ls(current_object, long=True)] = cmds.xform(
current_object,
query=True,
matrix=True)
Then if you move/rotate/scale the objects in Maya, you can revert like that:
for current_object in selected_objects_matrix:
cmds.xform(
current_object,
matrix=selected_objects_matrix[current_object])
you really just want to do what you have in reverse
setting the q=1 sets the command into query mode.
removing this flag defaults the command to edit mode
getAttr and setAttr are their respective commands, however you need to be aware of the data that youre setting. even though youre grabbing the s attribute above youre making that only grab the x value so when you set it you need to specify sx
cmds.xform ( m , ws = 1 , t = posValues)
cmds.xform( m , ws = 1 , rotation = rotValues )
cmds.setAttr ( m + '.sx', scaleValue) # sx because you are only grabbing the X Value
I have a function that produces an array within it, and I want to do work on the generated array outside of the function, in python. How can I make the function save the array such that this can be done?
Thanks!
My function is here:
def lane_emden(n, delxi=0.00001, xilim=25):
theta = 1
dtdx = 0
xi = 0.01
#Starting values
dtdx_values = [dtdx]
theta_values = [theta]
xi_values = [xi]
#Initial values for the lists
while theta>=0 and xi<=xilim :
dtdx_new = dtdx - ((2*(2/xi*dtdx)) + theta**n)*delxi
theta_new = theta + delxi*dtdx_new
xi_new = xi + delxi
#Equations to create new values for iterative diff eq solving
dtdx = dtdx_new
theta = theta_new
xi = xi_new
#Replace the old values with the new ones
dtdx_values.append(dtdx)
theta_values.append(theta)
xi_values.append(xi)
#Store these new values in previously defined lists
results = np.array((theta_values, xi_values))
#create an array of the results (probably done incorrectly)
return results
#This is how I tried to get the array saved outside the function
I'm very new to Python, any help would be greatly appreciated!
[Edit] Function call as requested.
Input
lane_emden(5)
Output
array([[ 1.00000000e+00, 1.00000000e+00, 1.00000000e+00, ...,
2.10576105e-01, 2.10576063e-01, 2.10576022e-01],
[ 1.00000000e-02, 1.00100000e-02, 1.00200000e-02, ...,
2.49999900e+01, 2.50000000e+01, 2.50000100e+01]])
You already return your array, so now you just need to use it. array = lane_emden(3) for example.
Looks like you are using numpy: results = np.array((theta_values, xi_values)). The documentation for numpy.array() states the first argument must be an array-like object:
An array, any object exposing the array interface, an object whose array method returns an array, or any (nested) sequence.
I think you want numpy.asarray() instead: results = np.asarray((theta_values, xi_values)).