Hi Abel,

As long as your x,y,z are next to each other, you can transform from
your structure to an unstructured array via a view, which has very
little cost.  Though you need to be a bit careful with offsets, etc., if
there are also other elements in the structured dtype.

Example, with some extra fields:

dtype = np.dtype([("i", np.int64), ("x", np.float64), ("y", np.float64), ("z", 
np.float64), ("j", np.int64)])
atoms = np.array(
    [
       (1, 0.0, 0.0, 0.0, -1),
       (2, 1.0, 0.0, 0.0, -2),
       (3, 0.0, 1.0, 0.0, -3),
       (4, 1.0, 1.0, 1.0, -4),
    ],
    dtype=dtype,
)
dt2 = np.dtype([("i", np.int64), ("xyz", np.float64, (3,)), ("j", np.int64)])
xyz = atoms.view(dt2)["xyz"]
xyz
# array([[0., 0., 0.],
#        [1., 0., 0.],
#        [0., 1., 0.],
#        [1., 1., 1.]])
xyz[:] = 9.
atoms
array([(1, 9., 9., 9., -1), (2, 9., 9., 9., -2), (3, 9., 9., 9., -3),
       (4, 9., 9., 9., -4)],
      dtype=[('i', '<i8'), ('x', '<f8'), ('y', '<f8'), ('z', '<f8'), ('j', 
'<i8')])

All the best,

Marten

abel.gutier...@ua.es writes:

> I'm using structured arrays to store atoms data produced by LAMMPS (I'm using 
> a structured array that follows its format). I need to rotate the positions:
>
> ```
> import numpy as np
>
> transform = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float64)
> dtype = np.dtype([("x", np.float64), ("y", np.float64), ("z", np.float64)])  
> # real case with more fields, integers, bools, strings
>
> atoms = np.array(
>     [
>         (0.0, 0.0, 0.0),
>         (1.0, 0.0, 0.0),
>         (0.0, 1.0, 0.0),
>         (1.0, 1.0, 1.0),
>     ],
>     dtype=dtype,
> )
>
> atoms[["x", "y", "z"]] = atoms[["x", "y", "z"]] @ transform.T
> ```
>
> But this produces:
>
> ```
> Traceback (most recent call last):
>   File "c:\Users\acgc99\Desktop\rotation.py", line 16, in <module>
>     atoms[["x", "y", "z"]] = atoms[["x", "y", "z"]] @ transform.T
>                              ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
> numpy._core._exceptions._UFuncNoLoopError: ufunc 'matmul' did not contain a 
> loop with signature matching types (dtype([('x', '<f8'), ('y', '<f8'), ('z', 
> '<f8')]), dtype('float64')) -> None
> ```
>
> I can convert to unstructured arrays, but I guess that doing that change 
> multiple times is not efficient when working with tens of millions of atoms.
> _______________________________________________
> NumPy-Discussion mailing list -- numpy-discussion@python.org
> To unsubscribe send an email to numpy-discussion-le...@python.org
> https://mail.python.org/mailman3//lists/numpy-discussion.python.org
> Member address: m...@astro.utoronto.ca
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3//lists/numpy-discussion.python.org
Member address: arch...@mail-archive.com

Reply via email to