Returns a datasheet with unique values in column j by grouping rows with the given function. The function takes a list of column values as input and returns a single value, e.g. FIRST, LAST, COUNT, MAX, MIN, SUM, AVG, STDEV, CONCATENATE. The function can also be
(self, j, function=FIRST, key=lambda v: v)
| 1793 | self.insert(len(self), row, default) |
| 1794 | |
| 1795 | def group(self, j, function=FIRST, key=lambda v: v): |
| 1796 | """ Returns a datasheet with unique values in column j by grouping rows with the given function. |
| 1797 | The function takes a list of column values as input and returns a single value, |
| 1798 | e.g. FIRST, LAST, COUNT, MAX, MIN, SUM, AVG, STDEV, CONCATENATE. |
| 1799 | The function can also be a list of functions (one for each column). |
| 1800 | TypeError will be raised when the function cannot handle the data in a column. |
| 1801 | The key argument can be used to map the values in column j, for example: |
| 1802 | key=lambda date: date.year to group Date objects by year. |
| 1803 | """ |
| 1804 | if isinstance(function, tuple): |
| 1805 | function = list(function) |
| 1806 | if not isinstance(function, list): |
| 1807 | function = [function] * self._m |
| 1808 | if len(function) < self._m: |
| 1809 | function+= [FIRST] * (self._m - len(function)) |
| 1810 | for i, f in enumerate(function): |
| 1811 | if i == j: # Group column j is always FIRST. |
| 1812 | f = FIRST |
| 1813 | if f == FIRST: |
| 1814 | function[i] = lambda a: a[+0] |
| 1815 | if f == LAST: |
| 1816 | function[i] = lambda a: a[-1] |
| 1817 | if f == COUNT: |
| 1818 | function[i] = lambda a: len(a) |
| 1819 | if f == MAX: |
| 1820 | function[i] = lambda a: max(a) |
| 1821 | if f == MIN: |
| 1822 | function[i] = lambda a: min(a) |
| 1823 | if f == SUM: |
| 1824 | function[i] = lambda a: _sum([x for x in a if x is not None]) |
| 1825 | if f == AVG: |
| 1826 | function[i] = lambda a: avg([x for x in a if x is not None]) |
| 1827 | if f == STDEV: |
| 1828 | function[i] = lambda a: stdev([x for x in a if x is not None]) |
| 1829 | if f == CONCATENATE: |
| 1830 | function[i] = lambda a: ",".join(decode_utf8(x) for x in a if x is not None) |
| 1831 | J = j |
| 1832 | # Map unique values in column j to a list of rows that contain this value. |
| 1833 | g = {}; [g.setdefault(key(v), []).append(i) for i, v in enumerate(self.columns[j])] |
| 1834 | # Map unique values in column j to a sort index in the new, grouped list. |
| 1835 | o = [(g[v][0], v) for v in g] |
| 1836 | o = dict([(v, i) for i, (ii,v) in enumerate(sorted(o))]) |
| 1837 | # Create a list of rows with unique values in column j, |
| 1838 | # applying the group function to the other columns. |
| 1839 | u = [None] * len(o) |
| 1840 | for v in g: |
| 1841 | # List the column values for each group row. |
| 1842 | u[o[v]] = [[list.__getitem__(self, i)[j] for i in g[v]] for j in range(self._m)] |
| 1843 | # Apply the group function to each row, except the unique value in column j. |
| 1844 | u[o[v]] = [function[j](column) for j, column in enumerate(u[o[v]])] |
| 1845 | u[o[v]][J] = v#list.__getitem__(self, i)[J] |
| 1846 | return Datasheet(rows=u) |
| 1847 | |
| 1848 | def map(self, function=lambda item: item): |
| 1849 | """ Applies the given function to each item in the matrix. |