0% found this document useful (0 votes)
14 views7 pages

Eneral Definitions

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views7 pages

Eneral Definitions

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

eneral definitions

• Namespace: A "holder" for various attributes (functions/methods), e.g. the set of built-in
nasignmes (containing basic functions such as abs()), or a class.
• Attribute: ~any name following a dot. For example, in the expression z.real, real is an attribute of
the object z. In the expression modname.funcname, modname is a module object and funcname
is an attribute of it.
• Scope: A textual region of a Python program where a namespace is directly accessible. "Directly
accessible" here means that an unqualified reference to a name attempts to find the name in
the namespace.
• Instance: A declared member of a class, as x = SomeClass().

*args, **kwargs

If a function (or class) has a parameter with * in front, all additional unnamed parameters will be
contained in a tuple with that name (conventionally called args).
If a function (or class) has a parameter with ** in front, all additional named parameters will be
contained in a dictionary with that name (conventionally called kwargs).

def f(x,y,*args,**kwargs):
print 'args =', args
print 'kwargs =', kwargs

f(3,4,5,5.,6,'few',z=3,gre='wallah')
outputs:
args = (5, 5.0, 6, 'few')
kwargs = {'z': 3, 'gre': 'wallah'}

From here:
One place where the use of *args and **kwargs is quite useful is for subclassing.
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2

class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)

Arrays

General on ndarrays here.

a = np.array([1, 2, 3.0]) # IDL: [1., 2., 3.]


b = np.arange(n) # IDL: indgen(n)
c = np.arange(2,5,.2) # IDL: findgen. [2., 2.2, ..., 4.8], 15 indices
d = np.linspace(2,5,15) # [2., 2.214, ..., 4.786, 5.], 15 indices
e = np.linspace(2,5,16) # [2., 2.2, ..., 4.8, 5.], 16 indices
f = np.logspace(0,3,7) # [1., 3.16, ..., 1000.], 7 indices

To find index of value in array A (real or integer) closest to x:


i = (abs(A - x)).argmin()
For integer arrays (which are exact) you can also use (also works for string arrays — nope, not in
Python 3 wait yes it does!):
i = np.where(A==x)[0][0] #where returns a tuple with an array of indices that are true.
# First [0] gets the array, second gets the first value in
this array.
# Of course, if multiple indices match, use only one [0].
For a list, use:
i = A.index(x)

If there are more than one occurrences, find them all with
L = [2,6,5,6,6,8]
inds = [ind for ind,val in enumerate(L) if val==6] # -> [1, 3, 4]

2D-arrays can be created like this (this seems a cumbersome way compared to ndarray(shape=...)):
nrow = 4
ncol = 2
A = np.array([[1.+i*j**2 for i in range(ncol)] for j in range(nrow)])
A[2,0] = 2.7 # Can also be referenced as A[2][0]
print A
[[ 1. 1. ]
[ 1. 2. ]
[ 2.7 5. ]
[ 1. 10. ]]

or:
A = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
print A
[[1 2 3]
[4 5 6]]
print A.shape
(2, 3)

or (better?) using ndarray:


A = np.ndarray(shape=(nrow,ncol)) # Puts numbers like 1.48219694e-323 in the elements.
"shape=" is optional.

or
np.matrix('1 2 5; 3 4 7') # -> shape = (2,3)
np.arange(25).reshape((5, 5))
np.array(range(25)).reshape((5, 5))
np.ndarray((5, 5)) # -> zero matrix

List comprehension (sort of a "compact for loop")


A = [2*i**2 for i in range(5)] # [0,2,8,18,32]
tr = sum([x for (i,j),x in np.ndenumerate(M)]) # trace of a square matrix M

Index picking
A = np.array([1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9])
A<4 # Condition: Boolean array [True, True, True, False, False, False,
False, False]
# A must be an array, not a list, in order to make a comparison
np.where(A<4) # The indices where the condition is true: [0, 1, 2]
A[np.where(A<4)] # The part of A where condition is true: [1.2, 2.3, 3.4]
A[A<4] # - " -
(A>4) & (A<7) # To have >1 conditions, put in ()'s and use & for AND, or | for
OR. [<-- and/or (more)]
To get values / indices of matching elements in a list, use
L = [1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9]
vals = [x for x in L if (x>4 and x<7)] # -> [4.5, 5.6, 6.7]
inds = [i for i,x in enumerate(L) if (x>4 and x<7)] # -> [3, 4, 5]
Mixed type arrays
A = np.ndarray((3,2),dtype=object) # This will create an array A = array([[1, 1.0],
A[:,0] = 1 # [1, 1.0],
A[:,1] = 1. # [1, 1.0]],
dtype=object)
Elements can be overwritten with a new type.
Elements behave as expected for their type when doing math, so dividing A by 2 gives 0 and 0.5 for
column 0 and 1, respectively. NO LONGER IN PYTHON 3: Integer division (//) by 2 returns 0 in all
places, normal division (/) returns 0.5 in all places.
If writing to a file, you must specify the format. Otherwise it will be written as the “higher” type:
np.savetxt('few',A,fmt='%4d %5.2f')

Common elements
Works also for lists
A = np.array([0,3,6,9,12,15,18,21,24])
B = np.array([3,5,12,13,14,24])
np.nonzero(np.in1d(A,B))[0] # -> array([1, 4, 8]) ; indices of A's elements that are
present in B
np.nonzero(np.in1d(B,A))[0] # -> array([0, 2, 5]) ; indices of B's elements that are
present in A
np.in1d(A,B) # -> array([False, True, False, False, True, False, False, False, True],
dtype=bool)
A[np.in1d(A,B)] # -> array([ 3, 12, 24]) ; return the common elements

Every i'th element


Use [first_index:last_index+1:stride] (omitting first/last if they're 0th or len(array)–1, respectively)
B = range(100)
B[85::3] # -> [85, 88, 91, 94, 97]
Useful for plotting very large array
scatter(d[::100],v[::100],s=1,alpha=0.1) # plot only every 100th element

Pick out specific elements


For an array one may simply use A[ind], but for lists one must use list comprehensions (other
possibilities exist):
a = list(A)
ind = [0,5,6]
[a[i] for i in ind] # -> [1.2, 6.7, 7.8]

Remove element
From lists:
A = [1,3,5,6,3]
A.pop(1) # -> A = [1,5,6,3]; also return value at index 1 (i.e. 3)
del(A[1]) # -> A = [1,5,6,3]; do not return value at index 1
A.remove(3) # Remove first instance of "3" (-> A = [1,5,6,3])
From arrays:
A = np.array([1,3,5,6,3])
np.delete(A,[1,4]) # -> array([1,5,6])

Shift elements
A = [0,5,6,9,9]
np.roll(A,3) # -> [6,9,9,0,5]

Append/extend
• For lists: The difference is that extend() adds the elements individually, whereas append adds the
whole object:
o A = [6,6]
o A.extend([1,2,3]) # A = [6,6,1,2,3]
o A.append([1,2,3]) # A = [6,6,1,2,3,[1,2,3]]
• For numpy arrays:
o A = np.array([6,6])
o A = np.append(A,[1,2,3]) # A = array([6,6,1,2,3])
• For multiple numpy arrays, use:
o np.concatenate([A,B,C,...]) # A = array([6,6,1,2,3])
• Add element in sorted array
o Haven't found a better way than
▪ np.sort(np.append(A,x))
• Add element to sorted list
o Use bisect.insort,

Appending a row/column to a 2D array (from here, where it is also shown how to delete a
row/column):
A = np.arange(15).reshape(3,5) # 3x5 matrix
xcol = np.array([111,222,333]) # This has shape (3,), so use:
xcol = np.array([111,222,333]).reshape(3,1)
xrow = np.array([111,222,333,444,555]).reshape(1,5)
print np.append(A,xcol,axis=1)
[[ 0 1 2 3 4 111]
[ 5 6 7 8 9 222]
[ 10 11 12 13 14 333]]
print np.append(A,xrow,axis=0)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[ 10 11 12 13 14]
[111 222 333 444 555]]

Compare elements to value


np.less(A, 1e-6).all() # Check if all of A's elements are <1e-6

Repeating elements
A = [1,2,3] #
3 * A # -> [1,2,3,1,2,3,1,2,3]
np.repeat(A,3) # -> array([1,1,1,2,2,2,3,3,3])

astropy

from astropy import units as u

Check that argument has correct unit


• This gives TypeError if theta has no units, and UnitsError if theta has the wrong units:
o @u.quantity_input
def func(x,theta:u.deg):
:
• This way is perhaps a bit simpler, or at least gives you more control of the error message
(the u.Quantity() is necessary to convert an argument that has no units into a Quantity;
otherwise the is_equivalent() won't work):
o def func(x,theta):
assert (u.Quantity(theta)).unit.is_equivalent(u.deg), 'theta must have
dimensions of angle.'
:

Angular separation between points


from astropy.coordinates import SkyCoord
cSN = SkyCoord('00h25m17s', '+64d08m37s') # SN 1572A
cCas = SkyCoord('00h40m30.4411s', '+56d32m14.392s') # alpha Cas
theta = SkyCoord.separation(cSN,cCas)
theta # -> <Angle 7.83250747 deg>
theta.dms # -> dms_tuple(d=7.0, m=49.0, s=57.026875431900805)
theta.dms # -> dms_tuple(d=7.0, m=49.0, s=57.026875431900805)
theta.to_string(unit=u.degree, sep=('deg ', 'm ', 's')) # -> '7deg 49m 57.02687543s'

Find redshift corresponding to the value of some function


from astropy.cosmology import z_at_value
z_at_value(cosmo.age, 200*u.kyr, zmax=1e4) # Redshift when Universe was 200,000 yr

Define new units


MmtEver = u.def_unit('MmtEver', 1.61932344e14 * u.kg) # Mass of Mt. Everest

Classes

Example of a more or less generic class (more on classes can be found here):

class ClassName(object): # -> base class; if class should inherit from


another class, use that class name instead of 'object'
"""This class will...""" # Docstring
var2 = 42 # }__"member variables". Later referred to as
"self.var2" and self.dict1
dict1 = {} # } If set like this, they're also called "class
attributes", as opposed to "instance attributes",
# and if changed for one instance, it willl
change for all instances |
#
|
def __init__(self, arg1, arg2): #
Initialization |
self.arg1 = arg1 # Assign args to instance. This is how new
variables /__________________|
self.arg2 = arg2 # are passed into the class ("dot
notation") \

def printArgs(self): # Internal functions --- called "methods" --- that


only use arguments
print self.arg1 # already known do not take any other arguments
than self
print self.arg2

def addstuff(self,key,n):
"""Add stuff to dict1"""
self.dict1[key] = n

def rmstuff(self,key,n):
"""Remove stuff from dict1"""
del self.dict1[key]

def __repr__(self): #Use __repr__ to return a meaningful string with


"print classInstance",rather than something like <classInstance.ClassName object at
0x10605aed0>
n = len(self.dict1)
return 'This is a ClassName object, with arg1 = {0:5.2f} and {1:4d} element(s) in
dict1'.format(self.arg1, n) #Note: n, not self.n

classInstance = ClassName(123, 666.)


classInstance.addstuff('wallah',2) # Add key 'wallah' with value 2 to dict1
print classInstance # prints 'This is a ClassName object, with arg1 =
123.00 and 1 element(s) in dict1'
class SubClassName(ClassName):
def __init__(self, newarg1): Is this true? Do I need to init "old" arguments as
well?

================================================

How classes can be used for extending existing object:


class MyList(list):
@property #I think this isn't needed, but preferred. Has to do with "getters"
vs. "setters". OR DECORATOR??? If NOT used, then get the length with L.length() instead
L.length.
def length(self):
return len(self) #For some reason I previously subtracted 1 here

L = MyList([1, 2, 33, 51])


L.length # -> 4

Clip array

Can be used to set negative elements to zero:


a = np.array([2,1,1,-1,-3,0,1,3,4])
a.clip(min=0) # -> [2,1,1,0,0,0,1,3,4].
Also accepts keyword 'max'.
Both min and max can be arrays.

Color images from fits files


• With Matplotlib
• With aplpy

Continuation

Inside parentheses, brackets, and braces, Python has "implied continuation", i.e. you can just break the
line where you want, with or without indentation:
x = [0,1,3,4,
5,6]
or
x = [0,1,3,4,
5,6]
Otherwise, parentheses can be added for free, as in
(x,y,z,
w,v,u) = np.loadtxt('file.txt',unpack=True)
or the "\" continuation character can be used:
x,y,z,\
w,v,u = np.loadtxt('file.txt',unpack=True)
Which is more Pythonic is debated…

Convolution

use np.convolve(P1,P2,mode='same')
But:

It doesn't take an x axis as input, and assumes dx = 1. Hence, to give the correct area under the
resulting curve (which should be the product of the areas of P1 and P2), the result must be multiplied by
dx.
Furthermore, the result is shifted by [INVESTIGATE THIS]

You might also like