Getting the order of the keyword arguments passed through ** kwargs would be extremely useful in the particular project I'm working on. It is about creating a kind of nd numpy array with significant dimensions (now called dimarray), which is especially useful for processing geophysical data.
Now let's say that we have:
import numpy as np
from dimarray import Dimarray
def make_data(nlat, nlon):
""" generate some example data
"""
values = np.random.randn(nlat, nlon)
lon = np.linspace(-180,180,nlon)
lat = np.linspace(-90,90,nlat)
return lon, lat, values
What works:
>>> lon, lat, values = make_data(180,360)
>>> a = Dimarray(values, lat=lat, lon=lon)
>>> print a.lon[0], a.lat[0]
-180.0 -90.0
What not:
>>> lon, lat, data = make_data(180,180)
>>> a = Dimarray(values, lat=lat, lon=lon)
>>> print a.lon[0], a.lat[0]
-90.0, -180.0
The reason is because the signature of the Dimarray method __init__
(values, **kwargs)
, and since it kwargs
is an unordered dictionary (dict), the best thing it can do is to check for the form values
.
Of course, I want it to work for any measurements:
a = Dimarray(values, x1=.., x2=...,x3=...)
**kwargs
.
, , (values, axes, names, **kwargs)
:
a = Dimarray(values, [lat, lon], ["lat","lon"])
(ipython), , ( !) python, numpy .
. , , :
import inspect
def f(**kwargs):
print inspect.stack()[1][4]
return tuple([kwargs[k] for k in kwargs])
>>> print f(lon=360, lat=180)
[u'print f(lon=360, lat=180)\n']
(180, 360)
>>> print f(lat=180, lon=360)
[u'print f(lat=180, lon=360)\n']
(180, 360)
- , , stack() :
>>> print (f(lon=360, lat=180), f(lat=180, lon=360))
[u'print (f(lon=360, lat=180), f(lat=180, lon=360))\n']
[u'print (f(lon=360, lat=180), f(lat=180, lon=360))\n']
((180, 360), (180, 360))
- , , ? ( ) , , lon=360, lat=180
, - , ?
, , python , , (, , !!!).
: https://mail.python.org/pipermail/python-ideas/2011-January/009054.html
, ?
, ** kwargs , . - ?
: pandas, , numpy. gitHub.
EDIT: I, dimarray. .
EDIT2: , , Dimarray values
. , , , . , , , , names
. , ( Dimarray ), python.
3, : kazagistar:
, , name=""
units=""
, , , *args
kwargs
.
, :
* a:
a = Dimarray(values, lon=mylon, lat=mylat, name="myarray")
a = Dimarray(values, [mylat, mylon], ["lat", "lon"], name="myarray")
* b: kazagistar 2- , **kwargs
a = Dimarray(values, ("lat", mylat), ("lon",mylon), name="myarray")
* c: kazagistar 2- , **kwargs
( , **kwargs
names=
. )
a = Dimarray(values, lon=mylon, lat=mylat, name="myarray")
a = Dimarray(values, ("lat", mylat), ("lon",mylon), name="myarray")
* d: kazagistar 3- **kwargs
a = Dimarray(values, lon=mylon, lat=mylat, name="myarray")
a = Dimarray(values, [("lat", mylat), ("lon",mylon)], name="myarray")
, ( ?). b) c). , ** kwargs - . , , , , ...
. , , a), b) c) d)!
=====================
EDIT 4: : a)!, from_tuples. . , "x0", "x1" ..... , pandas, . ** kwargs . , .
a = Dimarray(values, lon=mylon, lat=mylat, name="myarray")
a = Dimarray(values, [mylat, mylon], ["lat", "lon"], name="myarray")
a = Dimarray.from_tuples(values, ("lat", mylat), ("lon",mylon), name="myarray")
5: pythonic ?: EDIT 4 api, dimarray, , Dimarray . , .
from dimarray import dimarray, Dimarray
a = dimarray(values, lon=mylon, lat=mylat, name="myarray")
b = dimarray(values, [("lat", mylat), ("lon",mylon)], name="myarray")
c = dimarray(values, [mylat, mylon, ...], ['lat','lon',...], name="myarray")
d = dimarray(values, [mylat, mylon, ...], name="myarray2")
:
e = Dimarray.from_dict(values, lon=mylon, lat=mylat)
e.set(name="myarray", inplace=True)
f = Dimarray.from_tuples(values, ("lat", mylat), ("lon",mylon), name="myarray")
g = Dimarray.from_list(values, [mylat, mylon, ...], ['lat','lon',...], name="myarray")
h = Dimarray.from_list(values, [mylat, mylon, ...], name="myarray")
d) h) "x0", "x1" .., mylat, mylon Axis ( , Axes and Axis , ).
:
class Dimarray(object):
""" ndarray with meaningful dimensions and clean interface
"""
def __init__(self, values, axes, **kwargs):
assert isinstance(axes, Axes), "axes must be an instance of Axes"
self.values = values
self.axes = axes
self.__dict__.update(kwargs)
@classmethod
def from_tuples(cls, values, *args, **kwargs):
axes = Axes.from_tuples(*args)
return cls(values, axes)
@classmethod
def from_list(cls, values, axes, names=None, **kwargs):
if names is None:
names = ["x{}".format(i) for i in range(len(axes))]
return cls.from_tuples(values, *zip(axes, names), **kwargs)
@classmethod
def from_dict(cls, values, names=None,**kwargs):
axes = Axes.from_dict(shape=values.shape, names=names, **kwargs)
return cls(values, axes)
():
def dimarray(values, axes=None, names=None, name=..,units=..., **kwargs):
""" my wrapper with all fancy options
"""
if len(kwargs) > 0:
new = Dimarray.from_dict(values, axes, **kwargs)
elif axes[0] is tuple:
new = Dimarray.from_tuples(values, *axes, **kwargs)
else:
new = Dimarray.from_list(values, axes, names=names, **kwargs)
new.set(name=name, units=units, ..., inplace=True)
return new
, , - args,
. .
. python ?
( )
=====================
(EDIT: , a), b), c), d) ), , :
* a :
def __init__(self, values, axes=None, names=None, units="",name="",..., **kwargs):
""" schematic representation of Dimarray init method
"""
if len(kwargs) > 0:
axes = Axes.from_dict(shape=values.shape, names=names, **kwargs)
else:
axes = Axes.from_list(axes, names)
...
self.values = values
self.axes = axes
self.name = name
self.units = units
* b) c) :
def __init__(self, values, *args, **kwargs):
...
b) , , kwargs, self.__dict__.update(kwargs)
. .
c) :
def __init__(self, values, *args, **kwargs):
""" most flexible for interactive use
"""
default_attrs = {'name':'', 'units':'', ...}
for k in kwargs:
if k in 'name', 'units', ...:
setattr(self, k) = kwargs.pop(k)
else:
setattr(self, k) = default_attrs[k]
if len(kwargs) > 0:
axes = Axes.from_dict(shape=values.shape, names=names, **kwargs)
else:
names, numpy_axes = zip(*args)
axes = Axes.from_list(numpy_axes, names)
, () , name= ", units =" " .
* d: clear __init__
def __init__(self, values, axes, name="", units="", ..., **kwaxes)
.
==========
EDIT, FYI. axes
, , dims=
labels=
. dimarray github. kazagistar.