3

I am currently having the problem parsing a string to a numpy array.

The string look like this:

input = '{{13,1},{2,1},{4,4},{1,7},{9,1}}'

The string represents a sparse vector, where the vector itself is delimited by curly brackets. Each entry, itself delimited by curly brackets, indicates which indices have which entries. The first entry in the list encodes the dimensions of the vector.

In the above example, the vector has length of 13 and 4 entries which are different from 0.

output = np.array([0,7,1,0,4,0,0,0,0,1,0,0,0])

After parsing it to an array, I have to parse to back to a string in its dense format, with the format:

stringoutput = '{0,7,1,0,4,0,0,0,0,1,0,0,0}'

While I managed to parse the numpy array to a string, I ran into the problem of having the wrong brackets (i.e. the build in array2string function uses [], while I need {})

I am open for any suggestions that help, solving this efficiently (even for large sparse vectors).

Thank you.

\edit: The given vector is always one dimensional, i.e. the second number within the first {} will always be 1. (and you only need 1 index to locate the position of elements)

1
  • Are they always 1-dimensional? Commented Nov 20, 2016 at 19:09

3 Answers 3

3

Here is a numpythonic way:

In [132]: inp = '{{13,1},{2,1},{4,4},{1,7},{9,1}}'

# Relace the brackets with parenthesis in order to convert the string to a valid python object.
In [133]: inp = ast.literal_eval(inp.replace('{', '(').replace('}', ')'))
# Unpack the dimention and rest of then values from input object
In [134]: dim, *rest = inp
# Creat the zero array based on extracted dimention 
In [135]: arr = np.zeros(dim)
# use `zip` to collecte teh indices and values separately in order to be use in `np.put`
In [136]: indices, values = zip(*rest)

In [137]: np.put(arr, indices, values)

In [138]: arr
Out[138]: 
array([[ 0.],
       [ 7.],
       [ 1.],
       [ 0.],
       [ 4.],
       [ 0.],
       [ 0.],
       [ 0.],
       [ 0.],
       [ 1.],
       [ 0.],
       [ 0.],
       [ 0.]])
Sign up to request clarification or add additional context in comments.

Comments

1

I like @Kasramvd's approach, but figured I'd put this one out there as well:

In [116]: r = (list(map(int, a.split(','))) for a in input[2:-2].split('},{'))

In [118]: l = np.zeros(next(r)[0], np.int)

In [119]: for a in r:
     ...:     l[a[0]] = a[1]
     ...:    

In [122]: s = '{' + ','.join(map(str, l)) + '}'

In [123]: s
Out[123]: '{0,7,1,0,4,0,0,0,0,1,0,0,0}'

Comments

1

This is based on @Kasramvd's answer. I adjusted how the other values are populated.

from @Kasramvd

import numpy as np
import ast

inp = '{{13,1},{2,1},{4,4},{1,7},{9,1}}'
inp = ast.literal_eval(inp.replace('{', '(').replace('}', ')'))
dim, *rest = inp

my adjustments

a = np.zeros(dim, dtype=int)
r = np.array(rest)
a[r[:, 0], 0] = r[:, 1]

a

array([[0],
       [7],
       [1],
       [0],
       [4],
       [0],
       [0],
       [0],
       [0],
       [1],
       [0],
       [0],
       [0]])

in one dimension

a = np.zeros(dim[0], dtype=int)
r = np.array(rest)
a[r[:, 0]] = r[:, 1]

a

array([0, 7, 1, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0])

Comments

Your Answer

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.