46

I have a list of Num_tuples tuples that all have the same length Dim_tuple

xlist = [tuple_1, tuple_2, ..., tuple_Num_tuples]

For definiteness, let's say Num_tuples=3 and Dim_tuple=2

xlist = [(1, 1.1), (2, 1.2), (3, 1.3)]

I want to convert xlist into a structured numpy array xarr using a user-provided list of column names user_names and a user-provided list of variable types user_types

user_names = [name_1, name_2, ..., name_Dim_tuple]
user_types = [type_1, type_2, ..., type_Dim_tuple]

So in the creation of the numpy array,

dtype = [(name_1,type_1), (name_2,type_2), ..., (name_Dim_tuple, type_Dim_tuple)]

In the case of my toy example desired end product would look something like:

xarr['name1']=np.array([1,2,3])
xarr['name2']=np.array([1.1,1.2,1.3])

How can I slice xlist to create xarr without any loops?

nucsit026
7287 silver badges17 bronze badges
asked Jan 27, 2015 at 17:58
3
  • without any loops is this possible without loops? What about list comprehension? Also, have you tried anything? Commented Jan 27, 2015 at 18:03
  • Yes, though the only thing I've gotten to work are hard-coding solutions that first involve xlist --> np.array(xlist). Commented Jan 27, 2015 at 18:11
  • For example, xtemp = np.array(xlist), and x1=np.array(xtemp[:,1]), this creates a numpy array of one-element tuples, which is not what I want. I can't seem to get the slicing right, that's the entire problem. Should be simple, I realize. Commented Jan 27, 2015 at 18:16

2 Answers 2

54

A list of tuples is the correct way of providing data to a structured array:

In [273]: xlist = [(1, 1.1), (2, 1.2), (3, 1.3)]
In [274]: dt=np.dtype('int,float')
In [275]: np.array(xlist,dtype=dt)
Out[275]: 
array([(1, 1.1), (2, 1.2), (3, 1.3)], 
 dtype=[('f0', '<i4'), ('f1', '<f8')])
In [276]: xarr = np.array(xlist,dtype=dt)
In [277]: xarr['f0']
Out[277]: array([1, 2, 3])
In [278]: xarr['f1']
Out[278]: array([ 1.1, 1.2, 1.3])

or if the names are important:

In [280]: xarr.dtype.names=['name1','name2']
In [281]: xarr
Out[281]: 
array([(1, 1.1), (2, 1.2), (3, 1.3)], 
 dtype=[('name1', '<i4'), ('name2', '<f8')])

http://docs.scipy.org/doc/numpy/user/basics.rec.html#filling-structured-arrays

chrisaycock
38.2k15 gold badges94 silver badges128 bronze badges
answered Jan 27, 2015 at 18:10
Sign up to request clarification or add additional context in comments.

1 Comment

This got me to exactly where I started from.
-2

hpaulj's answer is interesting but horrifying :)

The modern Pythonic way to have named columns is to use pandas, a highly popular package built on top of numpy:

import pandas as pd
xlist = [(1, 1.1), (2, 1.2), (3, 1.3)]
# Cast name1 to int because pandas' default is float
df = pd.DataFrame(xlist, columns=['name1', 'name2']).astype({'name1':int})
print(df)

This gives you a DataFrame, df, which is the structure you want:

 name1 name2
0 1 1.1
1 2 1.2
2 3 1.3

You can do all kinds of wonderful things with this, like slicing and various operations.

For example, to the create the xarr dictionary requested in the original question:

>>> xarr = {k:np.array(v) for k,v in df.to_dict(orient='list').items()}
>>> xarr
{'name1': array([1, 2, 3]), 'name2': array([1.1, 1.2, 1.3])}
answered Oct 17, 2022 at 16:39

3 Comments

This answer does not answer the original question, and suggests using a much larger and bloated package that can be avoided using the accepted answer.
OK fwyzard, good point; I have added a one-liner to convert to the exact format requested in the original question. Also, pandas' "bloat" could be considered a feature, not a bug: unless you have a very good reason, it is probably better to rely on a well-supported package rather than to try to "roll your own" solution to a basic data transformation task.
Hi Michael, I do agree with reusing well-supported software. However import pandas takes more than 0.5 seconds on an dual AMD EPYC 7763 server... for a simple transformation, that's likely more than the time taken by the operation itself :-( I'd be much happier with pandas if it could be used in a more modular way.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.