Skip to content

Commit

Permalink
Merge pull request #575 from GavinHuttley/develop
Browse files Browse the repository at this point in the history
Miscellany
  • Loading branch information
GavinHuttley committed Mar 15, 2020
2 parents 262d7d3 + 21bfe1c commit 2141e26
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 17 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,25 @@ Our `cogent3.app` module provides a very different approach to using the library
$ pip install cogent3
```

### Installing with some other extra libraries, e.g. [plotly](https://github.com/plotly/plotly.py) and [pandas](https://github.com/pandas-dev/pandas) (optional)
### Install `extra` -- adds visualisation support

**NOTE:** Only available in the development version until release ≥2020.3

The `extra` group includes python libraries required for visualisation (i.e. [plotly](https://pypi.org/project/plotly/) and [psutil](https://pypi.org/project/psutil/) plus [pandas](https://pypi.org/project/pandas/) (optional)

```bash
$ pip install cogent3[extra]
```

### Installing the development version (optional)
### Install `dev` -- adds `cogent3` development related libraries

The `dev` group includes python libraries required for development of `cogent3`.

```bash
$ pip install cogent3[dev]
```

### Install the development version

```bash
$ pip install git+https://github.com/cogent3/cogent3.git@develop#egg=cogent3
Expand Down
28 changes: 14 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,30 +172,30 @@ def CythonExtension(module_name, **kw):
install_requires=["numpy", "scitrack", "tqdm", "tinydb"],
extras_require={
"dev": [
"pytest-azurepipelines",
"jupyterlab",
"black",
"click",
"ipykernel",
"ipywidgets",
"click",
"sphinx",
"sphinx_rtd_theme",
"sphinx-autobuild",
"sphinxcontrib-bibtex",
"numpydoc",
"nbformat",
"nbconvert",
"isort",
"jupyter_client",
"ipykernel",
"nbsphinx",
"jupyterlab",
"jupytext",
"nbconvert",
"nbformat",
"nbsphinx",
"numpydoc",
"pandas",
"plotly",
"psutil",
"pytest",
"pytest-azurepipelines",
"pytest-cov",
"pytest>=4.3.0",
"sphinx",
"sphinx-autobuild",
"sphinx_rtd_theme",
"sphinxcontrib-bibtex",
"tox",
"black",
"isort",
],
"extra": ["pandas", "plotly", "psutil"],
},
Expand Down
32 changes: 31 additions & 1 deletion src/cogent3/maths/stats/number.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from collections import defaultdict
from collections import Counter, defaultdict
from collections.abc import Mapping, MutableMapping

import numpy
Expand Down Expand Up @@ -204,6 +204,34 @@ def to_freqs(self):
result = CategoryFreqs(self, total=self.sum)
return result

def count(self, indices):
"""
Parameters
----------
indices
select element(s) from a multi-element tuple keys, must be int or
series of ints
Returns
-------
CategoryCounter
"""
if isinstance(indices, int):
indices = [indices]

counts = Counter()
for key in self:
try:
sub_key = tuple(key[i] for i in indices)
sub_key = sub_key[0] if len(sub_key) == 1 else sub_key
except IndexError:
msg = f"indices {indices} too big for key {key}"
raise IndexError(msg)
counts[sub_key] += self[key]

result = self.__class__(data=counts)
return result


class CategoryFreqs(MutableMapping, SummaryStatBase):
"""category frequencies with summary statistic attributes"""
Expand Down Expand Up @@ -287,6 +315,8 @@ def to_normalized(self):


class NumberCounter(CategoryCounter):
"""counts occurrences of numbers"""

def __init__(self, data=None):
super(NumberCounter, self).__init__(data=data)

Expand Down
57 changes: 57 additions & 0 deletions tests/test_maths/test_stats/test_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,63 @@ def test_numbers_update(self):
counts = number.CategoryCounter("AAAACCCGGGGT")
nums.update_from_counts(counts)

def test_count(self):
"""correctly counts across key dimensions"""
data = [
("T", "C"),
("T", "T"),
("T", "A"),
("G", "A"),
("G", "A"),
("A", "C"),
("A", "G"),
("T", "T"),
("T", "A"),
("T", "T"),
("A", "T"),
("A", "C"),
("A", "C"),
("T", "A"),
("A", "A"),
("A", "C"),
]
nums = number.CategoryCounter(data)
i0 = nums.count(0)
self.assertEqual(i0["T"], 7)
self.assertEqual(i0["G"], 2)
self.assertEqual(i0["A"], 7)
self.assertEqual(i0["C"], 0)
# works same if keys are strings
nums = number.CategoryCounter(["".join(e) for e in data])
i0 = nums.count(0)
self.assertEqual(i0["T"], 7)
self.assertEqual(i0["G"], 2)
self.assertEqual(i0["A"], 7)
self.assertEqual(i0["C"], 0)
with self.assertRaises(IndexError):
_ = nums.count([0, 3])

i0 = nums.count([0])
self.assertEqual(i0["G"], 2)
with self.assertRaises(IndexError):
_ = nums.count([0, 3])
i1 = nums.count(1)
self.assertEqual(i1["A"], 6)
self.assertEqual(i1["C"], 5)
self.assertEqual(i1["T"], 4)

data = {
("A", "C", "G"): 10,
("A", "T", "G"): 4,
("C", "C", "G"): 3,
("G", "C", "G"): 6,
}
nums = number.CategoryCounter(data)
i02 = nums.count([0, 2])
self.assertEqual(i02[("A", "G")], 14)
self.assertEqual(i02[("C", "G")], 3)
self.assertEqual(i02[("G", "G")], 6)


if __name__ == "__main__":
main()

0 comments on commit 2141e26

Please sign in to comment.