13

I can convert a string representation of a list to a list with ast.literal_eval. Is there an equivalent for a numpy array?

x = arange(4)
xs = str(x)
xs
'[0 1 2 3]'
# how do I convert xs back to an array

Using ast.literal_eval(xs) raises a SyntaxError. I can do the string parsing if I need to, but I thought there might be a better solution.

Community
  • 1
  • 1
jdmcbr
  • 4,626
  • 4
  • 22
  • 29
  • The numpy array doesn't provide a `repr` that can be used to reconstruct even a python list. You could doctor the string to recreate a list then create a numpy array from that e.g. `numpy.array(ast.literal_eval(', '.join(xs.split(' '))))` – Paul Rooney Aug 11 '16 at 03:24
  • Is it essential that you use `ast.literal_eval`? If so, then the answer is *no*, you can't get a numpy array from `literal_eval`. From the python documentation of `ast.literal_eval(node_or_string)`: "The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None." If what you really want is a convenient way to convert a numpy array to a string and then back to an array, please elaborate on that in the question. – Warren Weckesser Aug 11 '16 at 03:59
  • Sorry for not being clearer. I was curious of there was an analog for `ast.literal_eval` that worked for numpy arrays, but didn't expect to use `ast.literal_eval`. – jdmcbr Aug 11 '16 at 04:00

2 Answers2

14

For 1D arrays, Numpy has a function called fromstring, so it can be done very efficiently without extra libraries.

Briefly you can parse your string like this:

s = '[0 1 2 3]'
a = np.fromstring(s[1:-1], dtype=np.int, sep=' ')
print(a) # [0 1 2 3]

For nD arrays, one can use .replace() to remove the brackets and .reshape() to reshape to desired shape, or use Merlin's solution.

ntg
  • 9,002
  • 6
  • 48
  • 73
Da Tong
  • 1,771
  • 15
  • 22
14

Try this:

xs = '[0 1 2 3]'

import re, ast
ls = re.sub('\s+', ',', xs)
a = np.array(ast.literal_eval(ls))
a  # -> array([0, 1, 2, 3])    
wjandrea
  • 16,334
  • 5
  • 30
  • 53
Merlin
  • 19,645
  • 34
  • 108
  • 190
  • I think the other answer better answers my question as asked, yes. I cannot quite understand why you even ask this question. You had clearly answered before I accepted an answer. – jdmcbr Aug 12 '16 at 16:42
  • 2
    The reason is simple. The answer does not work for the code sample given! – Merlin Aug 12 '16 at 16:58
  • It is a self contained example that makes quite clear how to use `np.fromstring`, a function I'd forgotten about, for the problem I was trying to solve. I also said "I can do the string parsing if I need to" in my question. So I didn't learn anything from your answer, but I learned something from the other one. – jdmcbr Aug 12 '16 at 17:05
  • I am done here.. learning something is upvote, answering marked as correct on SO. The answer as chosen will lead ppl astray in the future. – Merlin Aug 12 '16 at 17:29
  • Both answers are valid depending on the case and for future readers like me both are beneficial. +1 to both. – ntg Feb 27 '19 at 10:14