Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2909ee3

Browse files
committed
Added a recs_join function to join a single column of multiple record arrays
svn path=/trunk/matplotlib/; revision=7746
1 parent 8a7bfd4 commit 2909ee3

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

lib/matplotlib/cbook.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,47 @@ def quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y):
16261626
import matplotlib.mlab as mlab
16271627
return mlab.quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y)
16281628

1629+
def align_iterators(func, *iterables):
1630+
"""
1631+
This generator takes a bunch of iterables that are ordered by func
1632+
It sends out ordered tuples (func(row), [rows from all iterators matching func(row)])
1633+
1634+
It is used by mlab.recs_join to join record arrays
1635+
"""
1636+
class myiter:
1637+
def __init__(self, it):
1638+
self.it = it
1639+
self.key = self.value = None
1640+
self.iternext()
1641+
1642+
def iternext(self):
1643+
try:
1644+
self.value = self.it.next()
1645+
self.key = func(self.value)
1646+
except StopIteration:
1647+
self.value = self.key = None
1648+
1649+
def __call__(self, key):
1650+
retval = None
1651+
if key == self.key:
1652+
retval = self.value
1653+
self.iternext()
1654+
elif self.key and key > self.key:
1655+
raise ValueError, "Iterator has been left behind"
1656+
return retval
1657+
1658+
# This can be made more efficient by not computing the minimum key for each iteration
1659+
iters = [myiter(it) for it in iterables]
1660+
minvals = minkey = True
1661+
while 1:
1662+
minvals = (filter(None, [it.key for it in iters]))
1663+
if minvals:
1664+
minkey = min(minvals)
1665+
yield (minkey, [it(minkey) for it in iters])
1666+
else:
1667+
break
1668+
1669+
16291670

16301671
if __name__=='__main__':
16311672
assert( allequal([1,1,1]) )

lib/matplotlib/mlab.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
:meth:`rec_join`
9292
join two record arrays on sequence of fields
9393
94+
:meth:`recs_join`
95+
a simple join of multiple recarrays using a single column as a key
96+
9497
:meth:`rec_groupby`
9598
summarize data by groups (similar to SQL GROUP BY)
9699
@@ -139,7 +142,7 @@
139142
"""
140143

141144
from __future__ import division
142-
import csv, warnings, copy, os
145+
import csv, warnings, copy, os, operator
143146

144147
import numpy as np
145148
ma = np.ma
@@ -1880,6 +1883,28 @@ def mapped_r2field(name):
18801883

18811884
return newrec
18821885

1886+
def recs_join(key, name, recs,missing=0.):
1887+
"""
1888+
*key* is the column name that acts as a key
1889+
*name* is the name that we want to join
1890+
*missing" is what the missing fields are replaced by
1891+
*recarrays* is a list of record arrays to join
1892+
1893+
returns a record array with columns [rowkey, name1, name2, ... namen]
1894+
1895+
>>> r = recs_join("date", "close", recs=[r0, r1], missing=0.)
1896+
1897+
"""
1898+
results = []
1899+
def extract(r):
1900+
if r is None: return missing
1901+
else: return r[name]
1902+
1903+
for rowkey, row in cbook.align_iterators(operator.attrgetter(key), *[iter(r) for r in recs]):
1904+
results.append([rowkey] + map(extract, row))
1905+
names = ",".join([key] + ["%s%d" % (name, d) for d in range(len(recs))])
1906+
return np.rec.fromrecords(results, names=names)
1907+
18831908

18841909
def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
18851910
converterd=None, names=None, missing='', missingd=None,

0 commit comments

Comments
 (0)