1

I am trying to assign new values to an array based on whether or not the stored value is <3. Coming from an R background this is how I would do it, but this gives me a syntax error in Python. What am I doing wrong, and what is the Python approach?

eurx=[1,2,3,4,5,6,7,'a',8]
sma50=3

tw=eurx
tw[eurx<sma50]=-1
tw[eurx>=sma50]=1
tw[(tw!=1)||(tw!=-1)]=0
print(tw)

GOAL:

-1
-1
1
1
1
1
1
0
1
2
  • 1
    That is not an array, that is a list Commented Dec 17, 2017 at 20:42
  • Also, this never makes a copy in Python, if that was your intent: tw=eurx Commented Dec 17, 2017 at 20:45

2 Answers 2

1

This is "too much R". A pythonic way would be to use functional filtering:

>>> map(lambda i: -2*int(i<sma50)+1 if type(i) == int else 0, eurx)
[-1, -1, 1, 1, 1, 1, 1, 0, 1]

Or just a simple for-loop with a few ifs:

>>> for i in eurx:
...   if type(i) != int: 
...     print 0
...   else: 
...     print -2*int(i<sma50)+1
... 
-1
-1
1
1
1
1
1
0
1

In general: don't try to guess the syntax. It's very simple, just read through some tutorials (e.g. https://docs.python.org/3/tutorial/introduction.html#first-steps-towards-programming)

Edit: the int conversion hack works as follows: you know you can convert bool to int, right?

>>> int(True)
1
>>> int(False)
0

If i<sma50 evaluates to True, int(i<sma50) will be 1. So yor numbers now are converted to ones if i is smaller than sma50 and to zeros otherwise. But apparently you want the values (-1, 1) instead of (1, 0). Just apply the transform -2x+1 and you're done!

Sign up to request clarification or add additional context in comments.

3 Comments

Could you explain the reason for the -2 ? Based on some googling for map and lambda it doesnt seem to be needed by either of those
Right, it's not required. You can insert another if to get the same result without the bool-to-int conversion hack.
The first code is not readable, and if you use map with a lambda, you might as well use a list comprehension. The second example doesn't return or define anything, it just prints elements.
1

Your desired syntax is pretty close to what you'd write in numpy.

The heterogeneous list doesn't make it easy, but here's an example:

>>> import numpy as np
>>> eurx=[1,2,3,4,5,6,7,'a',8]
>>> sma50 = 3
>>> tw = np.array([i if isinstance(i, int) else np.nan for i in eurx])
>>> tw
array([  1.,   2.,   3.,   4.,   5.,   6.,   7.,  nan,   8.])
>>> tw[tw < sma50] = -1
__main__:1: RuntimeWarning: invalid value encountered in less
>>> tw[tw >= sma50] = 1
__main__:1: RuntimeWarning: invalid value encountered in greater_equal
>>> tw
array([ -1.,  -1.,   1.,   1.,   1.,   1.,   1.,  nan,   1.])
>>> tw[np.isnan(tw)] = 0
>>> tw
array([-1., -1.,  1.,  1.,  1.,  1.,  1.,  0.,  1.])

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.