├── .gitignore
├── SOMPY.egg-info
├── top_level.txt
├── dependency_links.txt
├── requires.txt
├── PKG-INFO
└── SOURCES.txt
├── Capture.PNG
├── figure_1.png
├── figure_2-4.png
├── sompy
├── visualization
│ ├── __init__.py
│ ├── dotmap.pyc
│ ├── hitmap.pyc
│ ├── view.pyc
│ ├── __init__.pyc
│ ├── mapview.pyc
│ ├── umatrix.pyc
│ ├── histogram.pyc
│ ├── __pycache__
│ │ ├── view.cpython-35.pyc
│ │ ├── __init__.cpython-35.pyc
│ │ ├── bmuhits.cpython-35.pyc
│ │ ├── dotmap.cpython-35.pyc
│ │ ├── hitmap.cpython-35.pyc
│ │ ├── mapview.cpython-35.pyc
│ │ ├── umatrix.cpython-35.pyc
│ │ └── histogram.cpython-35.pyc
│ ├── hitmap.py
│ ├── bmuhits.py
│ ├── view.py
│ ├── histogram.py
│ ├── dotmap.py
│ ├── umatrix.py
│ └── mapview.py
├── __pycache__
│ ├── sompy.cpython-35.pyc
│ ├── __init__.cpython-35.pyc
│ ├── codebook.cpython-35.pyc
│ ├── decorators.cpython-35.pyc
│ ├── neighborhood.cpython-35.pyc
│ └── normalization.cpython-35.pyc
├── decorators.py
├── __init__.py
├── neighborhood.py
├── normalization.py
├── examples
│ ├── main.py
│ └── centroids_map.html
├── codebook.py
└── sompy.py
├── dist
├── SOMPY-1.0-py2.7.egg
└── SOMPY-1.0-py3.5.egg
├── .idea
└── vcs.xml
├── .directory
├── setup.py
├── README.md
├── LICENSE
└── data
├── eng-climate-summaries-British Columbia-10,2017.csv
├── eng-climate-summaries-British Columbia-12,2017.csv
└── eng-climate-summaries-British Columbia-8,2017.csv
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/SOMPY.egg-info/top_level.txt:
--------------------------------------------------------------------------------
1 | sompy
2 |
--------------------------------------------------------------------------------
/SOMPY.egg-info/dependency_links.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Capture.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/Capture.PNG
--------------------------------------------------------------------------------
/figure_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/figure_1.png
--------------------------------------------------------------------------------
/figure_2-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/figure_2-4.png
--------------------------------------------------------------------------------
/sompy/visualization/__init__.py:
--------------------------------------------------------------------------------
1 | from . import dotmap, histogram, hitmap, mapview, umatrix
2 |
--------------------------------------------------------------------------------
/SOMPY.egg-info/requires.txt:
--------------------------------------------------------------------------------
1 | numexpr >= 2.5
2 | numpy >= 1.7
3 | scikit-learn >= 0.16
4 | scipy >= 0.9
5 |
--------------------------------------------------------------------------------
/dist/SOMPY-1.0-py2.7.egg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/dist/SOMPY-1.0-py2.7.egg
--------------------------------------------------------------------------------
/dist/SOMPY-1.0-py3.5.egg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/dist/SOMPY-1.0-py3.5.egg
--------------------------------------------------------------------------------
/sompy/visualization/dotmap.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/dotmap.pyc
--------------------------------------------------------------------------------
/sompy/visualization/hitmap.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/hitmap.pyc
--------------------------------------------------------------------------------
/sompy/visualization/view.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/view.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__init__.pyc
--------------------------------------------------------------------------------
/sompy/visualization/mapview.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/mapview.pyc
--------------------------------------------------------------------------------
/sompy/visualization/umatrix.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/umatrix.pyc
--------------------------------------------------------------------------------
/sompy/visualization/histogram.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/histogram.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/sompy.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/sompy.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/codebook.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/codebook.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/decorators.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/decorators.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/neighborhood.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/neighborhood.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/__pycache__/normalization.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/normalization.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/view.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/view.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/bmuhits.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/bmuhits.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/dotmap.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/dotmap.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/hitmap.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/hitmap.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/mapview.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/mapview.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/umatrix.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/umatrix.cpython-35.pyc
--------------------------------------------------------------------------------
/sompy/visualization/__pycache__/histogram.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/histogram.cpython-35.pyc
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | <<<<<<< HEAD
3 | Timestamp=2017,2,7,17,30,1
4 | Version=3
5 |
6 | [Settings]
7 | HiddenFilesShown=true
8 | =======
9 | Timestamp=2017,2,8,12,4,41
10 | Version=3
11 | >>>>>>> 503c114584bd9cb91d18379b03a6c9f494d8b4fc
12 |
--------------------------------------------------------------------------------
/SOMPY.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 1.0
2 | Name: SOMPY
3 | Version: 1.0
4 | Summary: Self Organizing Maps Package
5 | Home-page: UNKNOWN
6 | Author: Vahid Moosavi and Sebastian Packmann
7 | Author-email: UNKNOWN
8 | License: UNKNOWN
9 | Description: UNKNOWN
10 | Platform: UNKNOWN
11 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | try:
2 | from setuptools import setup, find_packages
3 | except ImportError:
4 | from distutils.core import setup
5 |
6 |
7 | setup(
8 | name="SOMPY",
9 | version="1.0",
10 | description="Self Organizing Maps Package",
11 | author="Vahid Moosavi and Sebastian Packmann",
12 | packages=find_packages(),
13 | install_requires=['numpy >= 1.7', 'scipy >= 0.9',
14 | 'scikit-learn >= 0.16', 'numexpr >= 2.5']
15 | )
16 |
--------------------------------------------------------------------------------
/SOMPY.egg-info/SOURCES.txt:
--------------------------------------------------------------------------------
1 | setup.py
2 | SOMPY.egg-info/PKG-INFO
3 | SOMPY.egg-info/SOURCES.txt
4 | SOMPY.egg-info/dependency_links.txt
5 | SOMPY.egg-info/requires.txt
6 | SOMPY.egg-info/top_level.txt
7 | sompy/__init__.py
8 | sompy/codebook.py
9 | sompy/decorators.py
10 | sompy/neighborhood.py
11 | sompy/normalization.py
12 | sompy/sompy.py
13 | sompy/visualization/__init__.py
14 | sompy/visualization/bmuhits.py
15 | sompy/visualization/dotmap.py
16 | sompy/visualization/histogram.py
17 | sompy/visualization/hitmap.py
18 | sompy/visualization/mapview.py
19 | sompy/visualization/umatrix.py
20 | sompy/visualization/view.py
--------------------------------------------------------------------------------
/sompy/decorators.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from functools import wraps
3 | from time import time
4 |
5 |
6 | def timeit(log_level=logging.INFO, alternative_title=None):
7 | def wrap(f):
8 | @wraps(f) # keeps the f.__name__ outside the wrapper
9 | def wrapped_f(*args, **kwargs):
10 | t0 = time()
11 | result = f(*args, **kwargs)
12 | ts = round(time() - t0, 3)
13 |
14 | title = alternative_title or f.__name__
15 | logging.getLogger().log(
16 | log_level, " %s took: %f seconds" % (title, ts))
17 |
18 | return result
19 |
20 | return wrapped_f
21 | return wrap
22 |
--------------------------------------------------------------------------------
/sompy/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | from logging.config import dictConfig
3 | import matplotlib
4 |
5 | #matplotlib.use('Agg') # Use whatever backend is available
6 |
7 | dictConfig({
8 | "version": 1,
9 | "disable_existing_loggers": False,
10 | "root": {
11 | "level": "NOTSET",
12 | "handlers": ["console"]
13 | },
14 | "handlers": {
15 | "console": {
16 | "level": "DEBUG",
17 | "class": "logging.StreamHandler",
18 | "formatter": "basic"
19 | }
20 | },
21 | "formatters": {
22 | "basic": {
23 | "format": '%(message)s'
24 | }
25 | }
26 | })
27 |
28 |
29 |
30 | from .sompy import SOMFactory
31 | from .visualization import *
32 |
--------------------------------------------------------------------------------
/sompy/visualization/hitmap.py:
--------------------------------------------------------------------------------
1 | from .view import MatplotView
2 | from matplotlib import pyplot as plt
3 | import numpy as np
4 |
5 |
6 | class HitMapView(MatplotView):
7 |
8 | def _set_labels(self, cents, ax, labels):
9 | for i, txt in enumerate(labels):
10 | ax.annotate(txt, (cents[i, 1], cents[i, 0]), size=10, va="center")
11 |
12 | def show(self, som, data=None):
13 |
14 | try:
15 | codebook = getattr(som, 'cluster_labels')
16 | except:
17 | codebook = som.cluster()
18 |
19 | # codebook = getattr(som, 'cluster_labels', som.cluster())
20 | msz = som.codebook.mapsize
21 |
22 | self.prepare()
23 | ax = self._fig.add_subplot(111)
24 |
25 | if data:
26 | proj = som.project_data(data)
27 | cents = som.bmu_ind_to_xy(proj)
28 | self._set_labels(cents, ax, codebook[proj])
29 |
30 | else:
31 | cents = som.bmu_ind_to_xy(np.arange(0, msz[0]*msz[1]))
32 | self._set_labels(cents, ax, codebook)
33 |
34 | plt.imshow(codebook.reshape(msz[0], msz[1])[::], alpha=.5)
35 | plt.show()
36 |
37 | return cents
38 |
--------------------------------------------------------------------------------
/sompy/neighborhood.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import inspect
3 | import sys
4 |
5 | small = .000000000001
6 |
7 |
8 | class NeighborhoodFactory(object):
9 |
10 | @staticmethod
11 | def build(neighborhood_func):
12 | for name, obj in inspect.getmembers(sys.modules[__name__]):
13 | if inspect.isclass(obj):
14 | if hasattr(obj, 'name') and neighborhood_func == obj.name:
15 | return obj()
16 | else:
17 | raise Exception(
18 | "Unsupported neighborhood function '%s'" % neighborhood_func)
19 |
20 |
21 | class GaussianNeighborhood(object):
22 |
23 | name = 'gaussian'
24 |
25 | @staticmethod
26 | def calculate(distance_matrix, radius, dim):
27 | return np.exp(-1.0*distance_matrix/(2.0*radius**2)).reshape(dim, dim)
28 |
29 | def __call__(self, *args, **kwargs):
30 | return self.calculate(*args)
31 |
32 |
33 | class BubbleNeighborhood(object):
34 |
35 | name = 'bubble'
36 |
37 | @staticmethod
38 | def calculate(distance_matrix, radius, dim):
39 | def l(a, b):
40 | c = np.zeros(b.shape)
41 | c[a-b >= 0] = 1
42 | return c
43 |
44 | return l(radius,
45 | np.sqrt(distance_matrix.flatten())).reshape(dim, dim) + small
46 |
47 | def __call__(self, *args, **kwargs):
48 | return self.calculate(*args)
49 |
--------------------------------------------------------------------------------
/sompy/visualization/bmuhits.py:
--------------------------------------------------------------------------------
1 | from collections import Counter
2 |
3 | import matplotlib
4 | import numpy as np
5 | from matplotlib import pyplot as plt
6 |
7 | from .mapview import MapView
8 |
9 |
10 | class BmuHitsView(MapView):
11 | def _set_labels(self, cents, ax, labels, onlyzeros, fontsize):
12 | for i, txt in enumerate(labels):
13 | if onlyzeros == True:
14 | if txt > 0:
15 | txt = ""
16 | ax.annotate(txt, (cents[i, 1] + 0.5, cents[-(i+1), 0] + 0.5), va="center", ha="center", size=fontsize)
17 |
18 | def show(self, som, anotate=True, onlyzeros=False, labelsize=7, cmap="jet", logaritmic = False):
19 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
20 | axis_num) = self._calculate_figure_params(som, 1, 1)
21 |
22 | self.prepare()
23 | ax = plt.gca()
24 | counts = Counter(som._bmu[0])
25 | counts = [counts.get(x, 0) for x in range(som.codebook.mapsize[0] * som.codebook.mapsize[1])]
26 | mp = np.array(counts).reshape(som.codebook.mapsize[0],
27 | som.codebook.mapsize[1])
28 |
29 | if not logaritmic:
30 | norm = matplotlib.colors.Normalize(
31 | vmin=0,
32 | vmax=np.max(mp.flatten()),
33 | clip=True)
34 | else:
35 | norm = matplotlib.colors.LogNorm(
36 | vmin=1,
37 | vmax=np.max(mp.flatten()))
38 |
39 | msz = som.codebook.mapsize
40 |
41 | cents = som.bmu_ind_to_xy(np.arange(0, msz[0] * msz[1]))
42 |
43 | if anotate:
44 | self._set_labels(cents, ax, counts, onlyzeros, labelsize)
45 |
46 |
47 | pl = plt.pcolor(mp[::-1], norm=norm, cmap=cmap)
48 |
49 | plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]])
50 | ax.set_yticklabels([])
51 | ax.set_xticklabels([])
52 | plt.colorbar(pl)
53 |
54 | plt.show()
55 |
--------------------------------------------------------------------------------
/sompy/visualization/view.py:
--------------------------------------------------------------------------------
1 | from matplotlib import pyplot as plt
2 |
3 |
4 | class View(object):
5 | def __init__(self, width, height, title, show_axis=True, packed=True,
6 | text_size=2.8, show_text=True, col_size=6, *args, **kwargs):
7 | self.width = width
8 | self.height = height
9 | self.title = title
10 | self.show_axis = show_axis
11 | self.packed = packed
12 | self.text_size = text_size
13 | self.show_text = show_text
14 | self.col_size = col_size
15 |
16 | def prepare(self, *args, **kwargs):
17 | raise NotImplementedError()
18 |
19 | def save(self, filename):
20 | raise NotImplementedError()
21 |
22 | def show(self, *args, **kwrags):
23 | raise NotImplementedError()
24 |
25 |
26 | class MatplotView(View):
27 |
28 | def __init__(self, width, height, title, show_axis=True, packed=True,
29 | text_size=2.8, show_text=True, col_size=6, *args, **kwargs):
30 | super(MatplotView, self).__init__(width, height, title, show_axis,
31 | packed, text_size, show_text,
32 | col_size, *args, **kwargs)
33 | self._fig = None
34 |
35 | def __del__(self):
36 | self._close_fig()
37 |
38 | def _close_fig(self):
39 | if self._fig:
40 | plt.close(self._fig)
41 |
42 | def prepare(self, *args, **kwargs):
43 | self._close_fig()
44 | self._fig = plt.figure(figsize=(self.width, self.height))
45 | plt.title(self.title)
46 | plt.axis('off')
47 | plt.rc('font', **{'size': self.text_size})
48 |
49 | def save(self, filename, transparent=False, bbox_inches='tight', dpi=400):
50 | self._fig.savefig(filename, transparent=transparent, dpi=dpi,
51 | bbox_inches=bbox_inches)
52 |
53 | def show(self, *args, **kwrags):
54 | raise NotImplementedError()
55 |
--------------------------------------------------------------------------------
/sompy/normalization.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import sys
3 | import inspect
4 |
5 |
6 | class NormalizatorFactory(object):
7 |
8 | @staticmethod
9 | def build(type_name):
10 | for name, obj in inspect.getmembers(sys.modules[__name__]):
11 | if inspect.isclass(obj):
12 | if hasattr(obj, 'name') and type_name == obj.name:
13 | return obj()
14 | else:
15 | raise Exception("Unknown normalization type '%s'" % type_name)
16 |
17 |
18 | class Normalizator(object):
19 |
20 | def normalize(self, data):
21 | raise NotImplementedError()
22 |
23 | def normalize_by(self, raw_data, data):
24 | raise NotImplementedError()
25 |
26 | def denormalize_by(self, raw_data, data):
27 | raise NotImplementedError()
28 |
29 |
30 | class VarianceNormalizator(Normalizator):
31 |
32 | name = 'var'
33 |
34 | def _mean_and_standard_dev(self, data):
35 | return np.mean(data, axis=0), np.std(data, axis=0)
36 |
37 | def normalize(self, data):
38 | me, st = self._mean_and_standard_dev(data)
39 | st[st == 0] = 1 # prevent: when sd = 0, normalized result = NaN
40 | return (data-me)/st
41 |
42 | def normalize_by(self, raw_data, data):
43 | me, st = self._mean_and_standard_dev(raw_data)
44 | st[st == 0] = 1 # prevent: when sd = 0, normalized result = NaN
45 | return (data-me)/st
46 |
47 | def denormalize_by(self, data_by, n_vect):
48 | me, st = self._mean_and_standard_dev(data_by)
49 | return n_vect * st + me
50 |
51 |
52 | class RangeNormalizator(Normalizator):
53 |
54 | name = 'range'
55 |
56 |
57 | class LogNormalizator(Normalizator):
58 |
59 | name = 'log'
60 |
61 |
62 | class LogisticNormalizator(Normalizator):
63 |
64 | name = 'logistic'
65 |
66 |
67 | class HistDNormalizator(Normalizator):
68 |
69 | name = 'histd'
70 |
71 |
72 | class HistCNormalizator(Normalizator):
73 |
74 | name = 'histc'
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SOMPY
2 | -----
3 | A Python Library for Self Organizing Map (SOM)
4 |
5 | As much as possible, the structure of SOM is similar to `somtoolbox` in Matlab. It has the following functionalities:
6 |
7 | 1. Only Batch training, which is faster than online training. It has parallel processing option similar to `sklearn` format and it speeds up the training procedure, but it depends on the data size and mainly the size of the SOM grid.I couldn't manage the memory problem and therefore, I recommend single core processing at the moment. But nevertheless, the implementation of the algorithm is carefully done for all those important matrix calculations, such as `scipy` sparse matrix and `numexpr` for calculation of Euclidean distance.
8 | 2. PCA (or RandomPCA (default)) initialization, using `sklearn` or random initialization.
9 | 3. component plane visualization (different modes).
10 | 4. Hitmap.
11 | 5. U-Matrix visualization.
12 | 6. 1-d or 2-d SOM with only rectangular, planar grid. (works well in comparison with hexagonal shape, when I was checking in Matlab with somtoolbox).
13 | 7. Different methods for function approximation and predictions (mostly using Sklearn).
14 |
15 |
16 | ### Dependencies:
17 | SOMPY has the following dependencies (tested only with Python 2.7x):
18 | - numpy
19 | - scipy
20 | - scikit-learn
21 | - numexpr
22 | - matplotlib
23 | - pandas
24 | - ipdb
25 |
26 | ### Installation:
27 | ```Python
28 | python setup.py install
29 | ```
30 |
31 |
32 | Many thanks to @sebastiandev, the library is now standardized in a pythonic tradition. Below you can see some basic examples, showing how to use the library.
33 | But I recommend you to go through the codes. There are several functionalities already implemented, but not documented. I would be very happy to add your new examples here.
34 |
35 | [Basice Example](https://gist.github.com/sevamoo/035c56e7428318dd3065013625f12a11)
36 |
37 | ### Citation
38 |
39 | There is no published paper about this library. However if possible, please cite the library as follows:
40 |
41 | ```
42 | Main Contributers:
43 | Vahid Moosavi @sevamoo
44 | Sebastian Packmann @sebastiandev
45 | Iván Vallés @ivallesp
46 | ```
47 |
48 |
49 | For more information, you can contact me via sevamoo@gmail.com or svm@arch.ethz.ch, but please report an issue first.
50 |
51 |
52 |
53 |
54 | Thanks a lot.
55 | Best Vahid Moosavi
56 |
--------------------------------------------------------------------------------
/sompy/visualization/histogram.py:
--------------------------------------------------------------------------------
1 | from .view import MatplotView
2 | from matplotlib import pyplot as plt
3 | from matplotlib import cm
4 | from matplotlib.colors import LogNorm
5 | import numpy as np
6 |
7 |
8 | class Hist2d(MatplotView):
9 |
10 | def _fill_hist(self, x, y, mapsize, data_coords, what='train'):
11 | x = np.arange(.5, mapsize[1]+.5, 1)
12 | y = np.arange(.5, mapsize[0]+.5, 1)
13 | X, Y = np.meshgrid(x, y)
14 |
15 | if what == 'train':
16 | a = plt.hist2d(x, y, bins=(mapsize[1], mapsize[0]), alpha=.0,
17 | cmap=cm.jet)
18 | area = a[0].T * 12
19 | plt.scatter(data_coords[:, 1], mapsize[0] - .5 - data_coords[:, 0],
20 | s=area.flatten(), alpha=.9, c='None', marker='o',
21 | cmap='jet', linewidths=3, edgecolor='r')
22 |
23 | else:
24 | a = plt.hist2d(x, y, bins=(mapsize[1], mapsize[0]), alpha=.0,
25 | cmap=cm.jet, norm=LogNorm())
26 | area = a[0].T*50
27 | plt.scatter(data_coords[:, 1] + .5,
28 | mapsize[0] - .5 - data_coords[:, 0],
29 | s=area, alpha=0.9, c='None', marker='o', cmap='jet',
30 | linewidths=3, edgecolor='r')
31 | plt.scatter(data_coords[:, 1]+.5, mapsize[0]-.5-data_coords[:, 0],
32 | s=area, alpha=0.2, c='b', marker='o', cmap='jet',
33 | linewidths=3, edgecolor='r')
34 |
35 | plt.xlim(0, mapsize[1])
36 | plt.ylim(0, mapsize[0])
37 |
38 | def show(self, som, data=None):
39 | # First Step: show the hitmap of all the training data
40 | coord = som.bmu_ind_to_xy(som.project_data(som.data_raw))
41 |
42 | self.prepare()
43 |
44 | ax = self._fig.add_subplot(111)
45 | ax.xaxis.set_ticks([i for i in range(0, som.codebook.mapsize[1])])
46 | ax.yaxis.set_ticks([i for i in range(0, som.codebook.mapsize[0])])
47 | ax.xaxis.set_ticklabels([])
48 | ax.yaxis.set_ticklabels([])
49 | ax.grid(True, linestyle='-', linewidth=.5)
50 |
51 | self._fill_hist(coord[:, 1], coord[:, 0], som.codebook.mapsize,
52 | som.bmu_ind_to_xy(np.arange(som.codebook.nnodes)))
53 |
54 | if data:
55 | coord_d = som.bmu_ind_to_xy(som.project_data(data))
56 | self._fill_hist(coord[:, 1], coord[:, 0], som.codebook.mapsize,
57 | coord_d, 'data')
58 |
59 | plt.show()
60 |
--------------------------------------------------------------------------------
/sompy/visualization/dotmap.py:
--------------------------------------------------------------------------------
1 | from .view import MatplotView
2 | from matplotlib import pyplot as plt
3 | import numpy as np
4 |
5 |
6 | class DotMapView(MatplotView):
7 |
8 | def init_figure(self, dim, cols):
9 | no_row_in_plot = dim/cols + 1
10 | no_col_in_plot = dim if no_row_in_plot <= 1 else cols
11 | h = .1
12 | w = .1
13 | self.width = no_col_in_plot*2.5*(1+w)
14 | self.height = no_row_in_plot*2.5*(1+h)
15 | self.prepare()
16 |
17 | def plot(self, data, coords, msz0, msz1, colormap, dlen, dim, rows, cols):
18 | for i in range(dim):
19 | plt.subplot(rows, cols, i+1)
20 |
21 | # This uses the colors uniquely for each record, while in normal
22 | # views, it is based on the values within each dimensions. This is
23 | # important when we are dealing with time series. Where we don't
24 | # want to normalize colors within each time period, rather we like
25 | # to see the patterns of each data records in time.
26 | mn = np.min(data[:, :], axis=1)
27 | mx = np.max(data[:, :], axis=1)
28 |
29 | for j in range(dlen):
30 | plt.scatter(coords[j, 1],
31 | msz0-1-coords[j, 0],
32 | c=data[j, i],
33 | vmax=mx[j], vmin=mn[j],
34 | s=90,
35 | marker='.',
36 | edgecolor='None',
37 | cmap=colormap,
38 | alpha=1)
39 |
40 | eps = .0075
41 | plt.xlim(0-eps, msz1-1+eps)
42 | plt.ylim(0-eps, msz0-1+eps)
43 | plt.xticks([])
44 | plt.yticks([])
45 |
46 | def show(self, som, which_dim='all', colormap=None, cols=None):
47 | plt.cm.get_cmap(colormap) if colormap else plt.cm.get_cmap('RdYlBu_r')
48 |
49 | data = som.data_raw
50 | msz0, msz1 = som.codebook.mapsize
51 | coords = som.bmu_ind_to_xy(som.project_data(data))[:, :2]
52 | cols = cols if cols else 8 # 8 is arbitrary
53 | rows = data.shape[1]/cols+1
54 |
55 | if which_dim == 'all':
56 | dim = data.shape[0]
57 | self.init_figure(dim, cols)
58 | self.plot(data, coords, msz0, msz1, colormap, data.shape[0],
59 | data.shape[1], rows, cols)
60 |
61 | else:
62 | dim = 1 if type(which_dim) is int else len(which_dim)
63 | self.init_figure(dim, cols)
64 | self.plot(data, coords, msz0, msz1, colormap, data.shape[0],
65 | len(which_dim), rows, cols)
66 |
67 | plt.tight_layout()
68 | plt.subplots_adjust(hspace=.16, wspace=.05)
69 |
--------------------------------------------------------------------------------
/sompy/examples/main.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from sompy.sompy import SOMFactory
3 | import pandas as pd
4 | import glob
5 | import os
6 |
7 |
8 | # read in all csvs from folder
9 | path = '..\\..\\data\\'
10 | all_files = glob.glob(os.path.join(path, "*.csv"))
11 |
12 | # concat into one df
13 | df_from_each_file = (pd.read_csv(f, skiprows = 31) for f in all_files)
14 | concatenated_df = pd.concat(df_from_each_file, ignore_index=True)
15 |
16 | # get columns Lat, Long, Mean Temp, Max Temp, Min temp, Precipitation
17 | data = concatenated_df[['Lat', 'Long', 'Tm', 'Tx', 'Tn', 'P']]
18 | data = data.apply(pd.to_numeric, errors='coerce')
19 | data = data.dropna(how='any')
20 | names = ['Latitude', "longitude", 'Monthly Median temperature (C)','Monthly Max temperature (C)', 'Monthly Min temperature (C)', 'Monthly total precipitation (mm)']
21 |
22 | print(data.head())
23 |
24 | # create the SOM network and train it. You can experiment with different normalizations and initializations
25 | sm = SOMFactory().build(data.values, normalization = 'var', initialization='pca', component_names=names)
26 | sm.train(n_job=1, verbose=False, train_rough_len=2, train_finetune_len=5)
27 |
28 | # The quantization error: average distance between each data vector and its BMU.
29 | # The topographic error: the proportion of all data vectors for which first and second BMUs are not adjacent units.
30 | topographic_error = sm.calculate_topographic_error()
31 | quantization_error = np.mean(sm._bmu[1])
32 | print ("Topographic error = %s; Quantization error = %s" % (topographic_error, quantization_error))
33 |
34 | # component planes view
35 | from sompy.visualization.mapview import View2D
36 | view2D = View2D(10,10,"rand data",text_size=12)
37 | view2D.show(sm, col_sz=4, which_dim="all", desnormalize=True)
38 |
39 | # U-matrix plot
40 | from sompy.visualization.umatrix import UMatrixView
41 |
42 | umat = UMatrixView(width=10,height=10,title='U-matrix')
43 | umat.show(sm)
44 |
45 | # do the K-means clustering on the SOM grid, sweep across k = 2 to 20
46 | from sompy.visualization.hitmap import HitMapView
47 | K = 20 # stop at this k for SSE sweep
48 | K_opt = 18 # optimal K already found
49 | [labels, km, norm_data] = sm.cluster(K,K_opt)
50 | hits = HitMapView(20,20,"Clustering",text_size=12)
51 | a=hits.show(sm)
52 |
53 | import gmplot
54 |
55 | gmap = gmplot.GoogleMapPlotter(54.2, -124.875224, 6)
56 | j = 0
57 | for i in km.cluster_centers_:
58 | gmap.marker(i[0],i[1],'red', title="Centroid " + str(j))
59 | j += 1
60 |
61 | gmap.draw("centroids_map.html")
62 |
63 |
64 | from bs4 import BeautifulSoup
65 |
66 | def insertapikey(fname, apikey):
67 | """put the google api key in a html file"""
68 | def putkey(htmltxt, apikey, apistring=None):
69 | """put the apikey in the htmltxt and return soup"""
70 | if not apistring:
71 | apistring = "https://maps.googleapis.com/maps/api/js?key=%s&callback=initMap"
72 | soup = BeautifulSoup(htmltxt, 'html.parser')
73 | body = soup.body
74 | src = apistring % (apikey, )
75 | tscript = soup.new_tag("script", src=src, async="defer")
76 | body.insert(-1, tscript)
77 | return soup
78 | htmltxt = open(fname, 'r').read()
79 | soup = putkey(htmltxt, apikey)
80 | newtxt = soup.prettify()
81 | open(fname, 'w').write(newtxt)
82 | API_KEY= 'YOUR API KEY HERE'
83 | insertapikey("centroids_map.html", API_KEY)
84 |
85 |
86 | gmap = gmplot.GoogleMapPlotter(54.2, -124.875224, 6)
87 | j = 0
88 | for i in km.cluster_centers_:
89 | gmap.marker(i[0],i[1],'red', title="Centroid " + str(j))
90 | j += 1
91 |
92 | gmap.draw("centroids_map.html")
93 |
--------------------------------------------------------------------------------
/sompy/visualization/umatrix.py:
--------------------------------------------------------------------------------
1 | from .view import MatplotView
2 | from matplotlib import pyplot as plt
3 | from pylab import imshow, contour
4 | from math import sqrt
5 | import numpy as np
6 | import scipy
7 |
8 |
9 | class UMatrixView(MatplotView):
10 |
11 | def build_u_matrix(self, som, distance=1, row_normalized=False):
12 | UD2 = som.calculate_map_dist()
13 | Umatrix = np.zeros((som.codebook.nnodes, 1))
14 | codebook = som.codebook.matrix
15 | if row_normalized:
16 | vector = som._normalizer.normalize_by(codebook.T, codebook.T,
17 | method='var').T
18 | else:
19 | vector = codebook
20 |
21 | for i in range(som.codebook.nnodes):
22 | codebook_i = vector[i][np.newaxis, :]
23 | neighborbor_ind = UD2[i][0:] <= distance
24 | neighborbor_codebooks = vector[neighborbor_ind]
25 | Umatrix[i] = scipy.spatial.distance_matrix(
26 | codebook_i, neighborbor_codebooks).mean()
27 |
28 | return Umatrix.reshape(som.codebook.mapsize)
29 |
30 | def show(self, som, distance2=1, row_normalized=False, show_data=True,
31 | contooor=True, blob=False, labels=False):
32 | umat = self.build_u_matrix(som, distance=distance2,
33 | row_normalized=row_normalized)
34 | msz = som.codebook.mapsize
35 | proj = som.project_data(som.data_raw)
36 | coord = som.bmu_ind_to_xy(proj)
37 |
38 | self._fig, ax = plt.subplots(1, 1)
39 | imshow(umat, cmap=plt.cm.get_cmap('RdYlBu_r'), alpha=1)
40 |
41 | if contooor:
42 | mn = np.min(umat.flatten())
43 | mx = np.max(umat.flatten())
44 | std = np.std(umat.flatten())
45 | md = np.median(umat.flatten())
46 | mx = md + 0*std
47 | contour(umat, np.linspace(mn, mx, 15), linewidths=0.7,
48 | cmap=plt.cm.get_cmap('Blues'))
49 |
50 | if show_data:
51 | plt.scatter(coord[:, 1], coord[:, 0], s=2, alpha=1., c='Gray',
52 | marker='o', cmap='jet', linewidths=3, edgecolor='Gray')
53 | plt.axis('off')
54 |
55 | if labels:
56 | if labels is True:
57 | labels = som.build_data_labels()
58 | for label, x, y in zip(labels, coord[:, 1], coord[:, 0]):
59 | plt.annotate(str(label), xy=(x, y),
60 | horizontalalignment='center',
61 | verticalalignment='center')
62 |
63 | ratio = float(msz[0])/(msz[0]+msz[1])
64 | self._fig.set_size_inches((1-ratio)*15, ratio*15)
65 | plt.tight_layout()
66 | plt.subplots_adjust(hspace=.00, wspace=.000)
67 | sel_points = list()
68 |
69 | if blob:
70 | from skimage.color import rgb2gray
71 | from skimage.feature import blob_log
72 |
73 | image = 1 / umat
74 | rgb2gray(image)
75 |
76 | # 'Laplacian of Gaussian'
77 | blobs = blob_log(image, max_sigma=5, num_sigma=4, threshold=.152)
78 | blobs[:, 2] = blobs[:, 2] * sqrt(2)
79 | imshow(umat, cmap=plt.cm.get_cmap('RdYlBu_r'), alpha=1)
80 | sel_points = list()
81 |
82 | for blob in blobs:
83 | row, col, r = blob
84 | c = plt.Circle((col, row), r, color='red', linewidth=2,
85 | fill=False)
86 | ax.add_patch(c)
87 | dist = scipy.spatial.distance_matrix(
88 | coord[:, :2], np.array([row, col])[np.newaxis, :])
89 | sel_point = dist <= r
90 | plt.plot(coord[:, 1][sel_point[:, 0]],
91 | coord[:, 0][sel_point[:, 0]], '.r')
92 | sel_points.append(sel_point[:, 0])
93 |
94 | plt.show()
95 | return sel_points, umat
96 |
--------------------------------------------------------------------------------
/sompy/examples/centroids_map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Google Maps - pygmaps
6 |
7 |
163 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/sompy/codebook.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from sklearn.decomposition import PCA
4 | #from sklearn.decomposition import RandomizedPCA# (randomizedpca is deprecated)
5 | from .decorators import timeit
6 |
7 |
8 | class InvalidNodeIndexError(Exception):
9 | pass
10 |
11 |
12 | class InvalidMapsizeError(Exception):
13 | pass
14 |
15 |
16 | class Codebook(object):
17 |
18 | def __init__(self, mapsize, lattice='rect'):
19 | self.lattice = lattice
20 |
21 | if 2 == len(mapsize):
22 | _size = [1, np.max(mapsize)] if 1 == np.min(mapsize) else mapsize
23 |
24 | elif 1 == len(mapsize):
25 | _size = [1, mapsize[0]]
26 | print('input was considered as the numbers of nodes')
27 | print('map size is [{dlen},{dlen}]'.format(dlen=int(mapsize[0]/2)))
28 | else:
29 | raise InvalidMapsizeError(
30 | "Mapsize is expected to be a 2 element list or a single int")
31 |
32 | self.mapsize = _size
33 | self.nnodes = mapsize[0]*mapsize[1]
34 | self.matrix = np.asarray(self.mapsize)
35 | self.initialized = False
36 |
37 | @timeit()
38 | def random_initialization(self, data):
39 | """
40 | :param data: data to use for the initialization
41 | :returns: initialized matrix with same dimension as input data
42 | """
43 | mn = np.tile(np.min(data, axis=0), (self.nnodes, 1))
44 | mx = np.tile(np.max(data, axis=0), (self.nnodes, 1))
45 | self.matrix = mn + (mx-mn)*(np.random.rand(self.nnodes, data.shape[1]))
46 | self.initialized = True
47 |
48 | @timeit()
49 | def pca_linear_initialization(self, data):
50 | """
51 | We initialize the map, just by using the first two first eigen vals and
52 | eigenvectors
53 | Further, we create a linear combination of them in the new map by
54 | giving values from -1 to 1 in each
55 |
56 | X = UsigmaWT
57 | XTX = Wsigma^2WT
58 | T = XW = Usigma
59 |
60 | // Transformed by W EigenVector, can be calculated by multiplication
61 | // PC matrix by eigenval too
62 | // Further, we can get lower ranks by using just few of the eigen
63 | // vevtors
64 |
65 | T(2) = U(2)sigma(2) = XW(2) ---> 2 is the number of selected
66 | eigenvectors
67 |
68 | (*) Note that 'X' is the covariance matrix of original data
69 |
70 | :param data: data to use for the initialization
71 | :returns: initialized matrix with same dimension as input data
72 | """
73 | cols = self.mapsize[1]
74 | coord = None
75 | pca_components = None
76 |
77 | if np.min(self.mapsize) > 1:
78 | coord = np.zeros((self.nnodes, 2))
79 | pca_components = 2
80 |
81 | for i in range(0, self.nnodes):
82 | coord[i, 0] = int(i / cols) # x
83 | coord[i, 1] = int(i % cols) # y
84 |
85 | elif np.min(self.mapsize) == 1:
86 | coord = np.zeros((self.nnodes, 1))
87 | pca_components = 1
88 |
89 | for i in range(0, self.nnodes):
90 | coord[i, 0] = int(i % cols) # y
91 |
92 | mx = np.max(coord, axis=0)
93 | mn = np.min(coord, axis=0)
94 | coord = (coord - mn)/(mx-mn)
95 | coord = (coord - .5)*2
96 | me = np.mean(data, 0)
97 | data = (data - me)
98 | tmp_matrix = np.tile(me, (self.nnodes, 1))
99 |
100 | # Randomized PCA is scalable
101 | #pca = RandomizedPCA(n_components=pca_components) # RandomizedPCA is deprecated.
102 | pca = PCA(n_components=pca_components, svd_solver='randomized')
103 |
104 | pca.fit(data)
105 | eigvec = pca.components_
106 | eigval = pca.explained_variance_
107 | norms = np.sqrt(np.einsum('ij,ij->i', eigvec, eigvec))
108 | eigvec = ((eigvec.T/norms)*eigval).T
109 |
110 | for j in range(self.nnodes):
111 | for i in range(eigvec.shape[0]):
112 | tmp_matrix[j, :] = tmp_matrix[j, :] + coord[j, i]*eigvec[i, :]
113 |
114 | self.matrix = np.around(tmp_matrix, decimals=6)
115 | self.initialized = True
116 |
117 | def grid_dist(self, node_ind):
118 | """
119 | Calculates grid distance based on the lattice type.
120 |
121 | :param node_ind: number between 0 and number of nodes-1. Depending on
122 | the map size, starting from top left
123 | :returns: matrix representing the distance matrix
124 | """
125 | if self.lattice == 'rect':
126 | return self._rect_dist(node_ind)
127 |
128 | elif self.lattice == 'hexa':
129 | return self._hexa_dist(node_ind)
130 |
131 | def _hexa_dist(self, node_ind):
132 | raise NotImplementedError()
133 |
134 | def _rect_dist(self, node_ind):
135 | """
136 | Calculates the distance of the specified node to the other nodes in the
137 | matrix, generating a distance matrix
138 |
139 | Ej. The distance matrix for the node_ind=5, that corresponds to
140 | the_coord (1,1)
141 | array([[2, 1, 2, 5],
142 | [1, 0, 1, 4],
143 | [2, 1, 2, 5],
144 | [5, 4, 5, 8]])
145 |
146 | :param node_ind: number between 0 and number of nodes-1. Depending on
147 | the map size, starting from top left
148 | :returns: matrix representing the distance matrix
149 | """
150 | rows = self.mapsize[0]
151 | cols = self.mapsize[1]
152 | dist = None
153 |
154 | # bmu should be an integer between 0 to no_nodes
155 | if 0 <= node_ind <= (rows*cols):
156 | node_col = int(node_ind % cols)
157 | node_row = int(node_ind / cols)
158 | else:
159 | raise InvalidNodeIndexError(
160 | "Node index '%s' is invalid" % node_ind)
161 |
162 | if rows > 0 and cols > 0:
163 | r = np.arange(0, rows, 1)[:, np.newaxis]
164 | c = np.arange(0, cols, 1)
165 | dist2 = (r-node_row)**2 + (c-node_col)**2
166 |
167 | dist = dist2.ravel()
168 | else:
169 | raise InvalidMapsizeError(
170 | "One or both of the map dimensions are invalid. "
171 | "Cols '%s', Rows '%s'".format(cols=cols, rows=rows))
172 |
173 | return dist
174 |
--------------------------------------------------------------------------------
/sompy/visualization/mapview.py:
--------------------------------------------------------------------------------
1 | import matplotlib
2 | from .view import MatplotView
3 | from matplotlib import pyplot as plt
4 | import numpy as np
5 | #import ipdb
6 |
7 |
8 | class MapView(MatplotView):
9 |
10 | def _calculate_figure_params(self, som, which_dim, col_sz):
11 |
12 | # add this to avoid error when normalization is not used
13 | if som._normalizer:
14 | codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix)
15 | else:
16 | codebook = som.codebook.matrix
17 |
18 | indtoshow, sV, sH = None, None, None
19 |
20 | if which_dim == 'all':
21 | dim = som._dim
22 | row_sz = np.ceil(float(dim) / col_sz)
23 | msz_row, msz_col = som.codebook.mapsize
24 | ratio_hitmap = msz_row / float(msz_col)
25 | ratio_fig = row_sz / float(col_sz)
26 | indtoshow = np.arange(0, dim).T
27 | sH, sV = 16, 16*ratio_fig*ratio_hitmap
28 |
29 | elif type(which_dim) == int:
30 | dim = 1
31 | msz_row, msz_col = som.codebook.mapsize
32 | ratio_hitmap = msz_row / float(msz_col)
33 | indtoshow = np.zeros(1)
34 | indtoshow[0] = int(which_dim)
35 | sH, sV = 16, 16 * ratio_hitmap
36 |
37 | elif type(which_dim) == list:
38 | max_dim = codebook.shape[1]
39 | dim = len(which_dim)
40 | row_sz = np.ceil(float(dim) / col_sz)
41 | msz_row, msz_col = som.codebook.mapsize
42 | ratio_hitmap = msz_row / float(msz_col)
43 | ratio_fig = row_sz / float(col_sz)
44 | indtoshow = np.asarray(which_dim).T
45 | sH, sV = 16, 16*ratio_fig*ratio_hitmap
46 |
47 | no_row_in_plot = dim / col_sz + 1 # 6 is arbitrarily selected
48 | if no_row_in_plot <= 1:
49 | no_col_in_plot = dim
50 | else:
51 | no_col_in_plot = col_sz
52 |
53 | axis_num = 0
54 |
55 | width = sH
56 | height = sV
57 |
58 | return (width, height, indtoshow, no_row_in_plot, no_col_in_plot,
59 | axis_num)
60 |
61 |
62 | class View2D(MapView):
63 |
64 | def show(self, som, what='codebook', which_dim='all', cmap=None,
65 | col_sz=None, desnormalize=False):
66 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
67 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz)
68 | self.prepare()
69 |
70 | if not desnormalize:
71 | codebook = som.codebook.matrix
72 | else:
73 | codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix)
74 |
75 | if which_dim == 'all':
76 | names = som._component_names[0]
77 | elif type(which_dim) == int:
78 | names = [som._component_names[0][which_dim]]
79 | elif type(which_dim) == list:
80 | names = som._component_names[0][which_dim]
81 |
82 |
83 | while axis_num < len(indtoshow):
84 | axis_num += 1
85 | ax = plt.subplot(no_row_in_plot, no_col_in_plot, axis_num)
86 | ind = int(indtoshow[axis_num-1])
87 |
88 | min_color_scale = np.mean(codebook[:, ind].flatten()) - 1 * np.std(codebook[:, ind].flatten())
89 | max_color_scale = np.mean(codebook[:, ind].flatten()) + 1 * np.std(codebook[:, ind].flatten())
90 | min_color_scale = min_color_scale if min_color_scale >= min(codebook[:, ind].flatten()) else \
91 | min(codebook[:, ind].flatten())
92 | max_color_scale = max_color_scale if max_color_scale <= max(codebook[:, ind].flatten()) else \
93 | max(codebook[:, ind].flatten())
94 | norm = matplotlib.colors.Normalize(vmin=min_color_scale, vmax=max_color_scale, clip=True)
95 |
96 | mp = codebook[:, ind].reshape(som.codebook.mapsize[0],
97 | som.codebook.mapsize[1])
98 | pl = plt.pcolor(mp[::-1], norm=norm)
99 | plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]])
100 | plt.title(names[axis_num - 1])
101 | ax.set_yticklabels([])
102 | ax.set_xticklabels([])
103 | plt.colorbar(pl)
104 |
105 | #plt.show()
106 |
107 |
108 | class View2DPacked(MapView):
109 |
110 | def _set_axis(self, ax, msz0, msz1):
111 | plt.axis([0, msz0, 0, msz1])
112 | plt.axis('off')
113 | ax.axis('off')
114 |
115 | def show(self, som, what='codebook', which_dim='all', cmap=None,
116 | col_sz=None):
117 | if col_sz is None:
118 | col_sz = 6
119 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
120 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz)
121 | codebook = som.codebook.matrix
122 |
123 | cmap = cmap or plt.cm.get_cmap('RdYlBu_r')
124 | msz0, msz1 = som.codebook.mapsize
125 | compname = som.component_names
126 | if what == 'codebook':
127 | h = .1
128 | w = .1
129 | self.width = no_col_in_plot*2.5*(1+w)
130 | self.height = no_row_in_plot*2.5*(1+h)
131 | self.prepare()
132 |
133 | while axis_num < len(indtoshow):
134 | axis_num += 1
135 | ax = self._fig.add_subplot(no_row_in_plot, no_col_in_plot,
136 | axis_num)
137 | ax.axis('off')
138 | ind = int(indtoshow[axis_num-1])
139 | mp = codebook[:, ind].reshape(msz0, msz1)
140 | plt.imshow(mp[::-1], norm=None, cmap=cmap)
141 | self._set_axis(ax, msz0, msz1)
142 |
143 | if self.show_text is True:
144 | plt.title(compname[0][ind])
145 | font = {'size': self.text_size}
146 | plt.rc('font', **font)
147 | if what == 'cluster':
148 | try:
149 | codebook = getattr(som, 'cluster_labels')
150 | except:
151 | codebook = som.cluster()
152 |
153 | h = .2
154 | w = .001
155 | self.width = msz0/2
156 | self.height = msz1/2
157 | self.prepare()
158 |
159 | ax = self._fig.add_subplot(1, 1, 1)
160 | mp = codebook[:].reshape(msz0, msz1)
161 | plt.imshow(mp[::-1], cmap=cmap)
162 |
163 | self._set_axis(ax, msz0, msz1)
164 |
165 | plt.subplots_adjust(hspace=h, wspace=w)
166 |
167 | plt.show()
168 |
169 |
170 | class View1D(MapView):
171 |
172 | def show(self, som, what='codebook', which_dim='all', cmap=None,
173 | col_sz=None):
174 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
175 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz)
176 | self.prepare()
177 |
178 | codebook = som.codebook.matrix
179 |
180 | while axis_num < len(indtoshow):
181 | axis_num += 1
182 | plt.subplot(no_row_in_plot, no_col_in_plot, axis_num)
183 | ind = int(indtoshow[axis_num-1])
184 | mp = codebook[:, ind]
185 | plt.plot(mp, '-k', linewidth=0.8)
186 |
187 | #plt.show()
188 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/sompy/sompy.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # Author: Vahid Moosavi (sevamoo@gmail.com)
4 | # Chair For Computer Aided Architectural Design, ETH Zurich
5 | # Future Cities Lab
6 | # www.vahidmoosavi.com
7 |
8 | # Contributor: Sebastian Packmann (sebastian.packmann@gmail.com)
9 |
10 |
11 | import tempfile
12 | import os
13 | import itertools
14 | import logging
15 |
16 | import numpy as np
17 |
18 | from time import time
19 | from multiprocessing.dummy import Pool
20 | from multiprocessing import cpu_count
21 | from scipy.sparse import csr_matrix
22 | from sklearn import neighbors
23 | from sklearn.externals.joblib import Parallel, delayed, load, dump
24 | import sys
25 |
26 | from .decorators import timeit
27 | from .codebook import Codebook
28 | from .neighborhood import NeighborhoodFactory
29 | from .normalization import NormalizatorFactory
30 |
31 | #lbugnon
32 | #import ipdb
33 | import sompy
34 | #
35 |
36 | class ComponentNamesError(Exception):
37 | pass
38 |
39 |
40 | class LabelsError(Exception):
41 | pass
42 |
43 |
44 | class SOMFactory(object):
45 |
46 | @staticmethod
47 | def build(data,
48 | mapsize=None,
49 | mask=None,
50 | mapshape='planar',
51 | lattice='rect',
52 | normalization='var',
53 | initialization='pca',
54 | neighborhood='gaussian',
55 | training='batch',
56 | name='sompy',
57 | component_names=None):
58 | """
59 | :param data: data to be clustered, represented as a matrix of n rows,
60 | as inputs and m cols as input features
61 | :param neighborhood: neighborhood object calculator. Options are:
62 | - gaussian
63 | - bubble
64 | - manhattan (not implemented yet)
65 | - cut_gaussian (not implemented yet)
66 | - epanechicov (not implemented yet)
67 |
68 | :param normalization: normalizer object calculator. Options are:
69 | - var
70 |
71 | :param mapsize: tuple/list defining the dimensions of the som.
72 | If single number is provided is considered as the number of nodes.
73 | :param mask: mask
74 | :param mapshape: shape of the som. Options are:
75 | - planar
76 | - toroid (not implemented yet)
77 | - cylinder (not implemented yet)
78 |
79 | :param lattice: type of lattice. Options are:
80 | - rect
81 | - hexa (not implemented yet)
82 |
83 | :param initialization: method to be used for initialization of the som.
84 | Options are:
85 | - pca
86 | - random
87 |
88 | :param name: name used to identify the som
89 | :param training: Training mode (seq, batch)
90 | """
91 | if normalization:
92 | normalizer = NormalizatorFactory.build(normalization)
93 | else:
94 | normalizer = None
95 | neighborhood_calculator = NeighborhoodFactory.build(neighborhood)
96 | return SOM(data, neighborhood_calculator, normalizer, mapsize, mask,
97 | mapshape, lattice, initialization, training, name, component_names)
98 |
99 |
100 | class SOM(object):
101 |
102 | def __init__(self,
103 | data,
104 | neighborhood,
105 | normalizer=None,
106 | mapsize=None,
107 | mask=None,
108 | mapshape='planar',
109 | lattice='rect',
110 | initialization='pca',
111 | training='batch',
112 | name='sompy',
113 | component_names=None):
114 | """
115 | Self Organizing Map
116 |
117 | :param data: data to be clustered, represented as a matrix of n rows,
118 | as inputs and m cols as input features
119 | :param neighborhood: neighborhood object calculator.
120 | :param normalizer: normalizer object calculator.
121 | :param mapsize: tuple/list defining the dimensions of the som. If
122 | single number is provided is considered as the number of nodes.
123 | :param mask: mask
124 | :param mapshape: shape of the som.
125 | :param lattice: type of lattice.
126 | :param initialization: method to be used for initialization of the som.
127 | :param name: name used to identify the som
128 | :param training: Training mode (seq, batch)
129 | """
130 | self._data = normalizer.normalize(data) if normalizer else data
131 | self._normalizer = normalizer
132 | self._dim = data.shape[1]
133 | self._dlen = data.shape[0]
134 | self._dlabel = None
135 | self._bmu = None
136 |
137 | self.name = name
138 | self.data_raw = data
139 | self.neighborhood = neighborhood
140 | self.mapshape = mapshape
141 | self.initialization = initialization
142 | self.mask = mask or np.ones([1, self._dim])
143 | mapsize = self.calculate_map_size(lattice) if not mapsize else mapsize
144 | self.codebook = Codebook(mapsize, lattice)
145 | self.training = training
146 | self._component_names = self.build_component_names() if component_names is None else [component_names]
147 | self._distance_matrix = self.calculate_map_dist()
148 |
149 | @property
150 | def component_names(self):
151 | return self._component_names
152 |
153 | @component_names.setter
154 | def component_names(self, compnames):
155 | if self._dim == len(compnames):
156 | self._component_names = np.asarray(compnames)[np.newaxis, :]
157 | else:
158 | raise ComponentNamesError('Component names should have the same '
159 | 'size as the data dimension/features')
160 |
161 | def build_component_names(self):
162 | cc = ['Variable-' + str(i+1) for i in range(0, self._dim)]
163 | return np.asarray(cc)[np.newaxis, :]
164 |
165 | @property
166 | def data_labels(self):
167 | return self._dlabel
168 |
169 | @data_labels.setter
170 | def data_labels(self, labels):
171 | """
172 | Set labels of the training data, it should be in the format of a list
173 | of strings
174 | """
175 | if labels.shape == (1, self._dlen):
176 | label = labels.T
177 | elif labels.shape == (self._dlen, 1):
178 | label = labels
179 | elif labels.shape == (self._dlen,):
180 | label = labels[:, np.newaxis]
181 | else:
182 | raise LabelsError('wrong label format')
183 |
184 | self._dlabel = label
185 |
186 | def build_data_labels(self):
187 | cc = ['dlabel-' + str(i) for i in range(0, self._dlen)]
188 | return np.asarray(cc)[:, np.newaxis]
189 |
190 | def calculate_map_dist(self):
191 | """
192 | Calculates the grid distance, which will be used during the training
193 | steps. It supports only planar grids for the moment
194 | """
195 | nnodes = self.codebook.nnodes
196 |
197 | distance_matrix = np.zeros((nnodes, nnodes))
198 | for i in range(nnodes):
199 | distance_matrix[i] = self.codebook.grid_dist(i).reshape(1, nnodes)
200 | return distance_matrix
201 |
202 | @timeit()
203 | def train(self,
204 | n_job=1,
205 | shared_memory=False,
206 | verbose='info',
207 | train_rough_len=None,
208 | train_rough_radiusin=None,
209 | train_rough_radiusfin=None,
210 | train_finetune_len=None,
211 | train_finetune_radiusin=None,
212 | train_finetune_radiusfin=None,
213 | train_len_factor=1,
214 | maxtrainlen=np.Inf):
215 | """
216 | Trains the som
217 |
218 | :param n_job: number of jobs to use to parallelize the traning
219 | :param shared_memory: flag to active shared memory
220 | :param verbose: verbosity, could be 'debug', 'info' or None
221 | :param train_len_factor: Factor that multiply default training lenghts (similar to "training" parameter in the matlab version). (lbugnon)
222 | """
223 | logging.root.setLevel(
224 | getattr(logging, verbose.upper()) if verbose else logging.ERROR)
225 |
226 | logging.info(" Training...")
227 | logging.debug((
228 | "--------------------------------------------------------------\n"
229 | " details: \n"
230 | " > data len is {data_len} and data dimension is {data_dim}\n"
231 | " > map size is {mpsz0},{mpsz1}\n"
232 | " > array size in log10 scale is {array_size}\n"
233 | " > number of jobs in parallel: {n_job}\n"
234 | " -------------------------------------------------------------\n")
235 | .format(data_len=self._dlen,
236 | data_dim=self._dim,
237 | mpsz0=self.codebook.mapsize[0],
238 | mpsz1=self.codebook.mapsize[1],
239 | array_size=np.log10(
240 | self._dlen * self.codebook.nnodes * self._dim),
241 | n_job=n_job))
242 |
243 | if self.initialization == 'random':
244 | self.codebook.random_initialization(self._data)
245 |
246 | elif self.initialization == 'pca':
247 | self.codebook.pca_linear_initialization(self._data)
248 |
249 | self.rough_train(njob=n_job, shared_memory=shared_memory, trainlen=train_rough_len,
250 | radiusin=train_rough_radiusin, radiusfin=train_rough_radiusfin,trainlen_factor=train_len_factor,maxtrainlen=maxtrainlen)
251 | self.finetune_train(njob=n_job, shared_memory=shared_memory, trainlen=train_finetune_len,
252 | radiusin=train_finetune_radiusin, radiusfin=train_finetune_radiusfin,trainlen_factor=train_len_factor,maxtrainlen=maxtrainlen)
253 | logging.debug(
254 | " --------------------------------------------------------------")
255 | logging.info(" Final quantization error: %f" % np.mean(self._bmu[1]))
256 |
257 | def _calculate_ms_and_mpd(self):
258 | mn = np.min(self.codebook.mapsize)
259 | max_s = max(self.codebook.mapsize[0], self.codebook.mapsize[1])
260 |
261 | if mn == 1:
262 | mpd = float(self.codebook.nnodes*10)/float(self._dlen)
263 | else:
264 | mpd = float(self.codebook.nnodes)/float(self._dlen)
265 | ms = max_s/2.0 if mn == 1 else max_s
266 |
267 | return ms, mpd
268 |
269 | def rough_train(self, njob=1, shared_memory=False, trainlen=None, radiusin=None, radiusfin=None,trainlen_factor=1,maxtrainlen=np.Inf):
270 | logging.info(" Rough training...")
271 |
272 | ms, mpd = self._calculate_ms_and_mpd()
273 | #lbugnon: add maxtrainlen
274 | trainlen = min(int(np.ceil(30*mpd)),maxtrainlen) if not trainlen else trainlen
275 | #print("maxtrainlen %d",maxtrainlen)
276 | #lbugnon: add trainlen_factor
277 | trainlen=int(trainlen*trainlen_factor)
278 |
279 | if self.initialization == 'random':
280 | radiusin = max(1, np.ceil(ms/3.)) if not radiusin else radiusin
281 | radiusfin = max(1, radiusin/6.) if not radiusfin else radiusfin
282 |
283 | elif self.initialization == 'pca':
284 | radiusin = max(1, np.ceil(ms/8.)) if not radiusin else radiusin
285 | radiusfin = max(1, radiusin/4.) if not radiusfin else radiusfin
286 |
287 | self._batchtrain(trainlen, radiusin, radiusfin, njob, shared_memory)
288 |
289 | def finetune_train(self, njob=1, shared_memory=False, trainlen=None, radiusin=None, radiusfin=None,trainlen_factor=1,maxtrainlen=np.Inf):
290 | logging.info(" Finetune training...")
291 |
292 | ms, mpd = self._calculate_ms_and_mpd()
293 |
294 | #lbugnon: add maxtrainlen
295 | if self.initialization == 'random':
296 | trainlen = min(int(np.ceil(50*mpd)),maxtrainlen) if not trainlen else trainlen
297 | radiusin = max(1, ms/12.) if not radiusin else radiusin # from radius fin in rough training
298 | radiusfin = max(1, radiusin/25.) if not radiusfin else radiusfin
299 |
300 | elif self.initialization == 'pca':
301 | trainlen = min(int(np.ceil(40*mpd)),maxtrainlen) if not trainlen else trainlen
302 | radiusin = max(1, np.ceil(ms/8.)/4) if not radiusin else radiusin
303 | radiusfin = 1 if not radiusfin else radiusfin # max(1, ms/128)
304 |
305 | #print("maxtrainlen %d",maxtrainlen)
306 |
307 | #lbugnon: add trainlen_factor
308 | trainlen=int(trainlen_factor*trainlen)
309 |
310 |
311 | self._batchtrain(trainlen, radiusin, radiusfin, njob, shared_memory)
312 |
313 | def _batchtrain(self, trainlen, radiusin, radiusfin, njob=1,
314 | shared_memory=False):
315 | radius = np.linspace(radiusin, radiusfin, trainlen)
316 |
317 | if shared_memory:
318 | data = self._data
319 | data_folder = tempfile.mkdtemp()
320 | data_name = os.path.join(data_folder, 'data')
321 | dump(data, data_name)
322 | data = load(data_name, mmap_mode='r')
323 |
324 | else:
325 | data = self._data
326 |
327 | bmu = None
328 |
329 | # X2 is part of euclidean distance (x-y)^2 = x^2 +y^2 - 2xy that we use
330 | # for each data row in bmu finding.
331 | # Since it is a fixed value we can skip it during bmu finding for each
332 | # data point, but later we need it calculate quantification error
333 | fixed_euclidean_x2 = np.einsum('ij,ij->i', data, data)
334 |
335 | logging.info(" radius_ini: %f , radius_final: %f, trainlen: %d\n" %
336 | (radiusin, radiusfin, trainlen))
337 |
338 | for i in range(trainlen):
339 | t1 = time()
340 | neighborhood = self.neighborhood.calculate(
341 | self._distance_matrix, radius[i], self.codebook.nnodes)
342 | bmu = self.find_bmu(data, njb=njob)
343 | self.codebook.matrix = self.update_codebook_voronoi(data, bmu,
344 | neighborhood)
345 |
346 | #lbugnon: ojo! aca el bmy[1] a veces da negativo, y despues de eso se rompe...hay algo raro ahi
347 | qerror = (i + 1, round(time() - t1, 3),
348 | np.mean(np.sqrt(bmu[1] + fixed_euclidean_x2))) #lbugnon: ojo aca me tiró un warning, revisar (commit sinc: 965666d3d4d93bcf48e8cef6ea2c41a018c1cb83 )
349 | #lbugnon
350 | #ipdb.set_trace()
351 | #
352 | logging.info(
353 | " epoch: %d ---> elapsed time: %f, quantization error: %f\n" %
354 | qerror)
355 | if np.any(np.isnan(qerror)):
356 | logging.info("nan quantization error, exit train\n")
357 |
358 | #sys.exit("quantization error=nan, exit train")
359 |
360 | bmu[1] = np.sqrt(bmu[1] + fixed_euclidean_x2)
361 | self._bmu = bmu
362 |
363 | @timeit(logging.DEBUG)
364 | def find_bmu(self, input_matrix, njb=1, nth=1):
365 | """
366 | Finds the best matching unit (bmu) for each input data from the input
367 | matrix. It does all at once parallelizing the calculation instead of
368 | going through each input and running it against the codebook.
369 |
370 | :param input_matrix: numpy matrix representing inputs as rows and
371 | features/dimension as cols
372 | :param njb: number of jobs to parallelize the search
373 | :returns: the best matching unit for each input
374 | """
375 | dlen = input_matrix.shape[0]
376 | y2 = np.einsum('ij,ij->i', self.codebook.matrix, self.codebook.matrix)
377 | if njb == -1:
378 | njb = cpu_count()
379 |
380 | pool = Pool(njb)
381 | chunk_bmu_finder = _chunk_based_bmu_find
382 |
383 | def row_chunk(part):
384 | return part * dlen // njb
385 |
386 | def col_chunk(part):
387 | return min((part+1)*dlen // njb, dlen)
388 |
389 | chunks = [input_matrix[row_chunk(i):col_chunk(i)] for i in range(njb)]
390 | b = pool.map(lambda chk: chunk_bmu_finder(chk, self.codebook.matrix, y2, nth=nth), chunks)
391 | pool.close()
392 | pool.join()
393 | bmu = np.asarray(list(itertools.chain(*b))).T
394 | del b
395 | return bmu
396 |
397 | @timeit(logging.DEBUG)
398 | def update_codebook_voronoi(self, training_data, bmu, neighborhood):
399 | """
400 | Updates the weights of each node in the codebook that belongs to the
401 | bmu's neighborhood.
402 |
403 | First finds the Voronoi set of each node. It needs to calculate a
404 | smaller matrix.
405 | Super fast comparing to classic batch training algorithm, it is based
406 | on the implemented algorithm in som toolbox for Matlab by Helsinky
407 | University.
408 |
409 | :param training_data: input matrix with input vectors as rows and
410 | vector features as cols
411 | :param bmu: best matching unit for each input data. Has shape of
412 | (2, dlen) where first row has bmu indexes
413 | :param neighborhood: matrix representing the neighborhood of each bmu
414 |
415 | :returns: An updated codebook that incorporates the learnings from the
416 | input data
417 | """
418 | row = bmu[0].astype(int)
419 | col = np.arange(self._dlen)
420 | val = np.tile(1, self._dlen)
421 | P = csr_matrix((val, (row, col)), shape=(self.codebook.nnodes,
422 | self._dlen))
423 | S = P.dot(training_data)
424 |
425 | # neighborhood has nnodes*nnodes and S has nnodes*dim
426 | # ---> Nominator has nnodes*dim
427 | nom = neighborhood.T.dot(S)
428 | nV = P.sum(axis=1).reshape(1, self.codebook.nnodes)
429 | denom = nV.dot(neighborhood.T).reshape(self.codebook.nnodes, 1)
430 | new_codebook = np.divide(nom, denom)
431 |
432 | return np.around(new_codebook, decimals=6)
433 |
434 | def project_data(self, data):
435 | """
436 | Projects a data set to a trained SOM. It is based on nearest
437 | neighborhood search module of scikitlearn, but it is not that fast.
438 | """
439 | clf = neighbors.KNeighborsClassifier(n_neighbors=1)
440 | labels = np.arange(0, self.codebook.matrix.shape[0])
441 | clf.fit(self.codebook.matrix, labels)
442 |
443 | # The codebook values are all normalized
444 | # we can normalize the input data based on mean and std of
445 | # original data
446 | data = self._normalizer.normalize_by(self.data_raw, data)
447 |
448 | return clf.predict(data)
449 |
450 | def predict_by(self, data, target, k=5, wt='distance'):
451 | # here it is assumed that target is the last column in the codebook
452 | # and data has dim-1 columns
453 | dim = self.codebook.matrix.shape[1]
454 | ind = np.arange(0, dim)
455 | indX = ind[ind != target]
456 | x = self.codebook.matrix[:, indX]
457 | y = self.codebook.matrix[:, target]
458 | n_neighbors = k
459 | clf = neighbors.KNeighborsRegressor(n_neighbors, weights=wt)
460 | clf.fit(x, y)
461 |
462 | # The codebook values are all normalized
463 | # we can normalize the input data based on mean and std of
464 | # original data
465 | dimdata = data.shape[1]
466 |
467 | if dimdata == dim:
468 | data[:, target] = 0
469 | data = self._normalizer.normalize_by(self.data_raw, data)
470 | data = data[:, indX]
471 |
472 | elif dimdata == dim-1:
473 | data = self._normalizer.normalize_by(self.data_raw[:, indX], data)
474 |
475 | predicted_values = clf.predict(data)
476 | predicted_values = self._normalizer.denormalize_by(
477 | self.data_raw[:, target], predicted_values)
478 | return predicted_values
479 |
480 | def predict(self, x_test, k=5, wt='distance'):
481 | """
482 | Similar to SKlearn we assume that we have X_tr, Y_tr and X_test. Here
483 | it is assumed that target is the last column in the codebook and data
484 | has dim-1 columns
485 |
486 | :param x_test: input vector
487 | :param k: number of neighbors to use
488 | :param wt: method to use for the weights
489 | (more detail in KNeighborsRegressor docs)
490 | :returns: predicted values for the input data
491 | """
492 | target = self.data_raw.shape[1]-1
493 | x_train = self.codebook.matrix[:, :target]
494 | y_train = self.codebook.matrix[:, target]
495 | clf = neighbors.KNeighborsRegressor(k, weights=wt)
496 | clf.fit(x_train, y_train)
497 |
498 | # The codebook values are all normalized
499 | # we can normalize the input data based on mean and std of
500 | # original data
501 | x_test = self._normalizer.normalize_by(
502 | self.data_raw[:, :target], x_test)
503 | predicted_values = clf.predict(x_test)
504 |
505 | return self._normalizer.denormalize_by(
506 | self.data_raw[:, target], predicted_values)
507 |
508 | def find_k_nodes(self, data, k=5):
509 | from sklearn.neighbors import NearestNeighbors
510 | # we find the k most similar nodes to the input vector
511 | neighbor = NearestNeighbors(n_neighbors=k)
512 | neighbor.fit(self.codebook.matrix)
513 |
514 | # The codebook values are all normalized
515 | # we can normalize the input data based on mean and std of
516 | # original data
517 | return neighbor.kneighbors(
518 | self._normalizer.normalize_by(self.data_raw, data))
519 |
520 | def bmu_ind_to_xy(self, bmu_ind):
521 | """
522 | Translates a best matching unit index to the corresponding
523 | matrix x,y coordinates.
524 |
525 | :param bmu_ind: node index of the best matching unit
526 | (number of node from top left node)
527 | :returns: corresponding (x,y) coordinate
528 | """
529 | rows = self.codebook.mapsize[0]
530 | cols = self.codebook.mapsize[1]
531 |
532 | # bmu should be an integer between 0 to no_nodes
533 | out = np.zeros((bmu_ind.shape[0], 3))
534 | out[:, 2] = bmu_ind
535 | out[:, 0] = rows-1-bmu_ind / cols
536 | out[:, 0] = bmu_ind / cols
537 | out[:, 1] = bmu_ind % cols
538 |
539 | return out.astype(int)
540 |
541 | def cluster(self, n_clusters=8, opt = 0):
542 | import sklearn.cluster as clust
543 |
544 | print("Performing K-means SSE elbow sweep...")
545 |
546 | # generate the bootstrap samples
547 | BTS = 20
548 | BTS_SIZE = 0.8
549 |
550 | normalized_data = self._normalizer.denormalize_by(self.data_raw,
551 | self.codebook.matrix)
552 |
553 | if(opt == 0):
554 | bts_len = int(BTS_SIZE * len(normalized_data))
555 | bootstrap_samples = []
556 | for i in range(BTS):
557 |
558 | temp = []
559 | for j in range(bts_len):
560 | index = np.random.randint(0,len(normalized_data))
561 | temp.append(normalized_data[index])
562 | temp = np.array(temp)
563 | bootstrap_samples.append(temp)
564 |
565 | SSE_BTS_K = []
566 | for i in range(2,n_clusters+1):
567 |
568 | SSE_K = []
569 | for l in range(BTS):
570 | print("Working on bootstrap sample " + str(l) + " K: " + str(i))
571 | km = clust.KMeans(n_clusters=i).fit(bootstrap_samples[l])
572 | SSE = 0
573 | # calculate the Sum of Square Errors and compute the elbow point
574 | for k in bootstrap_samples[l]:
575 | label = km.predict([k])[0]
576 | SSE = SSE + np.linalg.norm(k - km.cluster_centers_[label])
577 | SSE_K.append(SSE)
578 | # average the bootstrapped SSE's
579 | SSE_BTS_K.append(np.sum(SSE_K) / float(BTS))
580 |
581 |
582 |
583 | # find the index of the maximum value of the 1st difference and add 1 to get the optimal K
584 | first_diff = np.diff(SSE_BTS_K)
585 | print("SSE for k = 2 to " + str(n_clusters) + " " + str(SSE_BTS_K))
586 | index = np.argmax(first_diff) + 1
587 |
588 | print("Optimal K = " + str(index))
589 |
590 | else:
591 | index = opt
592 |
593 |
594 | km = clust.KMeans(n_clusters=index).fit(normalized_data)
595 |
596 | # print cluster centroids
597 | for i in range(index):
598 | print("Centroid " + str(i) + str(km.cluster_centers_[i]))
599 |
600 | self.cluster_labels = km.labels_
601 | return km.labels_, km, normalized_data
602 |
603 | def predict_probability(self, data, target, k=5):
604 | """
605 | Predicts probability of the input data to be target
606 |
607 | :param data: data to predict, it is assumed that 'target' is the last
608 | column in the codebook, so data hould have dim-1 columns
609 | :param target: target to predict probability
610 | :param k: k parameter on KNeighborsRegressor
611 | :returns: probability of data been target
612 | """
613 | dim = self.codebook.matrix.shape[1]
614 | ind = np.arange(0, dim)
615 | indx = ind[ind != target]
616 | x = self.codebook.matrix[:, indx]
617 | y = self.codebook.matrix[:, target]
618 |
619 | clf = neighbors.KNeighborsRegressor(k, weights='distance')
620 | clf.fit(x, y)
621 |
622 | # The codebook values are all normalized
623 | # we can normalize the input data based on mean and std of
624 | # original data
625 | dimdata = data.shape[1]
626 |
627 | if dimdata == dim:
628 | data[:, target] = 0
629 | data = self._normalizer.normalize_by(self.data_raw, data)
630 | data = data[:, indx]
631 |
632 | elif dimdata == dim-1:
633 | data = self._normalizer.normalize_by(self.data_raw[:, indx], data)
634 |
635 | weights, ind = clf.kneighbors(data, n_neighbors=k,
636 | return_distance=True)
637 | weights = 1./weights
638 | sum_ = np.sum(weights, axis=1)
639 | weights = weights/sum_[:, np.newaxis]
640 | labels = np.sign(self.codebook.matrix[ind, target])
641 | labels[labels >= 0] = 1
642 |
643 | # for positives
644 | pos_prob = labels.copy()
645 | pos_prob[pos_prob < 0] = 0
646 | pos_prob *= weights
647 | pos_prob = np.sum(pos_prob, axis=1)[:, np.newaxis]
648 |
649 | # for negatives
650 | neg_prob = labels.copy()
651 | neg_prob[neg_prob > 0] = 0
652 | neg_prob = neg_prob * weights * -1
653 | neg_prob = np.sum(neg_prob, axis=1)[:, np.newaxis]
654 |
655 | return np.concatenate((pos_prob, neg_prob), axis=1)
656 |
657 | def node_activation(self, data, target=None, wt='distance'):
658 | weights, ind = None, None
659 |
660 | if not target:
661 | clf = neighbors.KNeighborsClassifier(
662 | n_neighbors=self.codebook.nnodes)
663 | labels = np.arange(0, self.codebook.matrix.shape[0])
664 | clf.fit(self.codebook.matrix, labels)
665 |
666 | # The codebook values are all normalized
667 | # we can normalize the input data based on mean and std of
668 | # original data
669 | data = self._normalizer.normalize_by(self.data_raw, data)
670 | weights, ind = clf.kneighbors(data)
671 |
672 | # Softmax function
673 | weights = 1./weights
674 |
675 | return weights, ind
676 |
677 | def calculate_topographic_error(self):
678 | bmus1 = self.find_bmu(self.data_raw, njb=1, nth=1)
679 | bmus2 = self.find_bmu(self.data_raw, njb=1, nth=2)
680 | bmus_gap = np.abs((self.bmu_ind_to_xy(np.array(bmus1[0]))[:, 0:2] - self.bmu_ind_to_xy(np.array(bmus2[0]))[:, 0:2]).sum(axis=1))
681 | return np.mean(bmus_gap != 1)
682 |
683 | def calculate_map_size(self, lattice):
684 | """
685 | Calculates the optimal map size given a dataset using eigenvalues and eigenvectors. Matlab ported
686 | :lattice: 'rect' or 'hex'
687 | :return: map sizes
688 | """
689 | D = self.data_raw.copy()
690 | dlen = D.shape[0]
691 | dim = D.shape[1]
692 | munits = np.ceil(5 * (dlen ** 0.5))
693 | A = np.ndarray(shape=[dim, dim]) + np.Inf
694 |
695 | for i in range(dim):
696 | D[:, i] = D[:, i] - np.mean(D[np.isfinite(D[:, i]), i])
697 |
698 | for i in range(dim):
699 | for j in range(dim):
700 | c = D[:, i] * D[:, j]
701 | c = c[np.isfinite(c)]
702 | A[i, j] = sum(c) / len(c)
703 | A[j, i] = A[i, j]
704 |
705 | VS = np.linalg.eig(A)
706 | eigval = sorted(np.linalg.eig(A)[0])
707 | if eigval[-1] == 0 or eigval[-2] * munits < eigval[-1]:
708 | ratio = 1
709 | else:
710 | ratio = np.sqrt(eigval[-1] / eigval[-2])
711 |
712 | if lattice == "rect":
713 | size1 = min(munits, round(np.sqrt(munits / ratio)))
714 | else:
715 | size1 = min(munits, round(np.sqrt(munits / ratio*np.sqrt(0.75))))
716 |
717 | size2 = round(munits / size1)
718 |
719 | return [int(size1), int(size2)]
720 |
721 |
722 | # Since joblib.delayed uses Pickle, this method needs to be a top level
723 | # method in order to be pickled
724 | # Joblib is working on adding support for cloudpickle or dill which will allow
725 | # class methods to be pickled
726 | # when that that comes out we can move this to SOM class
727 | def _chunk_based_bmu_find(input_matrix, codebook, y2, nth=1):
728 | """
729 | Finds the corresponding bmus to the input matrix.
730 |
731 | :param input_matrix: a matrix of input data, representing input vector as
732 | rows, and vectors features/dimention as cols
733 | when parallelizing the search, the input_matrix can be
734 | a sub matrix from the bigger matrix
735 | :param codebook: matrix of weights to be used for the bmu search
736 | :param y2:
737 | """
738 | dlen = input_matrix.shape[0]
739 | nnodes = codebook.shape[0]
740 | bmu = np.empty((dlen, 2))
741 |
742 | # It seems that small batches for large dlen is really faster:
743 | # that is because of ddata in loops and n_jobs. for large data it slows
744 | # down due to memory needs in parallel
745 | blen = min(50, dlen)
746 | i0 = 0
747 |
748 | while i0+1 <= dlen:
749 | low = i0
750 | high = min(dlen, i0+blen)
751 | i0 = i0+blen
752 | ddata = input_matrix[low:high+1]
753 | d = np.dot(codebook, ddata.T)
754 | d *= -2
755 | d += y2.reshape(nnodes, 1)
756 | bmu[low:high+1, 0] = np.argpartition(d, nth, axis=0)[nth-1]
757 | bmu[low:high+1, 1] = np.partition(d, nth, axis=0)[nth-1]
758 | del ddata
759 |
760 | return bmu
761 |
762 |
763 |
764 |
--------------------------------------------------------------------------------
/data/eng-climate-summaries-British Columbia-10,2017.csv:
--------------------------------------------------------------------------------
1 | "Environment and Climate Change Canada"
2 | "Monthly Values for October - 2017"
3 |
4 | "Legend"
5 | "Stn_Name","Station Name"
6 | "Lat","Latitude (North + , degrees)"
7 | "Long","Longitude (West - , degrees)"
8 | "Prov","Province"
9 | "Tm","Mean Temperature (°C)"
10 | "DwTm","Days without Valid Mean Temperature"
11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)"
12 | "Tx","Highest Monthly Maximum Temperature (°C)"
13 | "DwTx","Days without Valid Maximum Temperature"
14 | "Tn","Lowest Monthly Minimum Temperature (°C)"
15 | "DwTn","Days without Valid Minimum Temperature"
16 | "S","Snowfall (cm)"
17 | "DwS","Days without Valid Snowfall"
18 | "S%N","Percent of Normal (1981-2010) Snowfall"
19 | "P","Total Precipitation (mm)"
20 | "DwP","Days without Valid Precipitation"
21 | "P%N","Percent of Normal (1981-2010) Precipitation"
22 | "S_G","Snow on the ground at the end of the month (cm)"
23 | "Pd","Number of days with Precipitation 1.0 mm or more"
24 | "BS","Bright Sunshine (hours)"
25 | "DwBS","Days without Valid Bright Sunshine"
26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine"
27 | "HDD","Degree Days below 18 °C"
28 | "CDD","Degree Days above 18 °C"
29 | "Clim_ID","Climate Identifier"
30 | "NA","Not Available"
31 |
32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID"
33 | "CHEMAINUS","48.935","-123.742","BC","10.9","0",NA,"18.5","0","4.0","0","0.0","0",NA,"153.9","0",NA,"0.0","9","","",NA,"220.4","0.0","1011500"
34 | "LAKE COWICHAN","48.829","-124.052","BC","9.2","14","-0.5","22.5","9","-1.0","10","0.0","29",NA,"267.0","15",NA,"","12","","",NA,"149.1","0.0","1012055"
35 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"16.1","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475"
36 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","10.6","0",NA,"18.8","0","4.0","0","",,NA,"110.8","0",NA,"","10","",,NA,"228.5","0.0","1012710"
37 | "GALIANO NORTH","48.985","-123.573","BC","11.1","4",NA,"18.5","4","5.0","4","0.0","4",NA,"76.8","4",NA,"0.0","7","","",NA,"186.5","0.0","10130MN"
38 | "MALAHAT","48.575","-123.530","BC","10.1","0",NA,"17.6","0","2.3","0","",,NA,"127.8","0",NA,"","10","",,NA,"244.4","0.0","1014820"
39 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"0.0","5",NA,"165.6","5",NA,"0.0","11","","",NA,"","","1015105"
40 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"0.0","0","0.0","134.8","0","124.0","0.0","11","","",NA,"","","1015628"
41 | "NORTH COWICHAN","48.824","-123.719","BC","9.7","0",NA,"21.3","0","-0.5","0","",,NA,"128.2","0",NA,"","10","",,NA,"258.2","0.0","1015630"
42 | "NORTH PENDER ISLAND","48.764","-123.287","BC","11.3","12",NA,"20.5","12","5.0","12","0.0","12",NA,"53.6","12",NA,"","5","","",NA,"126.9","0.0","1015638"
43 | "RACE ROCKS","48.298","-123.531","BC","11.2","0",NA,"17.5","0","6.4","0","",,NA,"",,NA,"","","",,NA,"212.0","0.0","1016640"
44 | "SAANICHTON CDA","48.622","-123.419","BC","10.6","6","0.3","19.0","3","3.0","3","0.0","3",NA,"102.5","3",NA,"","9","","",NA,"183.8","0.0","1016940"
45 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","11.4","2","0.6","19.0","2","5.0","2","0.0","2",NA,"102.6","2",NA,"0.0","9","","",NA,"191.8","0.0","1016995"
46 | "SAANICHTON MT NEWTON","48.598","-123.427","BC","",,NA,"",,"",,"0.0","25",NA,"87.0","25",NA,"","6","","",NA,"","","1016RM0"
47 | "SATURNA CAPMON CS","48.775","-123.128","BC","10.2","3",NA,"18.1","3","3.8","1","",,NA,"24.2","3",NA,"","7","",,NA,"219.3","0.0","1017099"
48 | "SATURNA ISLAND CS","48.784","-123.045","BC","11.3","2",NA,"16.5","2","6.4","2","",,NA,"57.0","2",NA,"","8","",,NA,"193.7","0.0","1017101"
49 | "SHAWNIGAN LAKE","48.647","-123.626","BC","10.0","0","0.1","20.0","0","2.0","0","0.0","0","0.0","124.6","0","109.0","0.0","9","","",NA,"246.9","0.0","1017230"
50 | "SHERINGHAM POINT","48.377","-123.921","BC","11.0","0",NA,"17.1","0","6.5","0","",,NA,"124.4","0",NA,"","11","",,NA,"216.9","0.0","1017254"
51 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","10.4","0",NA,"19.9","0","2.4","0","",,NA,"103.6","0",NA,"","10","",,NA,"234.6","0.0","1018598"
52 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"0.0","2",NA,"134.2","2",NA,"","10","","",NA,"","","1018605"
53 | "VICTORIA GONZALES CS","48.413","-123.325","BC","11.4","0",NA,"19.3","0","5.6","0","",,NA,"92.0","0",NA,"","10","",,NA,"205.7","0.0","1018611"
54 | "VICTORIA INTL A","48.647","-123.426","BC","10.2","0",NA,"19.8","0","1.2","0","0.0","0",NA,"92.3","0",NA,"","7","",,NA,"243.3","0.0","1018621"
55 | "WILLIAM HEAD","48.340","-123.539","BC","11.3","0","0.9","16.5","0","5.0","0","0.0","0","0.0","128.6","0","118.0","0.0","9","","",NA,"207.8","0.0","1018935"
56 | "BALLENAS ISLAND","49.350","-124.160","BC","11.0","0",NA,"17.4","0","7.2","0","",,NA,"61.0","0",NA,"","9","",,NA,"217.9","0.0","1020590"
57 | "CAMPBELL RIVER A","49.952","-125.273","BC","8.1","0","-0.5","20.5","0","-3.5","0","0.0","0","0.0","150.2","0","93.0","0.0","16","","",NA,"306.9","0.0","1021261"
58 | "CAPE MUDGE","49.998","-125.195","BC","10.3","0","0.7","20.0","0","4.5","0","0.0","0","0.0","120.2","0","71.0","0.0","14","","",NA,"238.9","0.0","1021330"
59 | "CHROME ISLAND","49.472","-124.683","BC","11.0","0",NA,"20.0","0","4.0","0","0.0","0",NA,"135.0","0",NA,"0.0","11","","",NA,"218.3","0.0","1021500"
60 | "COMOX A","49.717","-124.900","BC","9.7","0","0.3","19.6","0","1.6","0","0.0","0","0.0","90.3","0","74.0","","10","",,NA,"256.3","0.0","1021830"
61 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","9.7","1",NA,"20.0","1","0.5","1","0.0","1",NA,"107.2","1",NA,"0.0","16","","",NA,"249.2","0.0","1021960"
62 | "COURTENAY GRANTHAM","49.763","-124.999","BC","9.5","7",NA,"19.5","7","4.0","7","0.0","7",NA,"110.6","7",NA,"","12","","",NA,"202.9","0.0","1021988"
63 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","9.3","8",NA,"20.5","5","-1.0","4","0.0","4",NA,"120.3","4",NA,"0.0","10","","",NA,"199.9","0.0","1021989"
64 | "ENTRANCE ISLAND","49.209","-123.811","BC","11.2","0",NA,"16.8","0","7.3","0","",,NA,"40.4","0",NA,"","7","",,NA,"211.5","0.0","1022689"
65 | "FANNY ISLAND","50.454","-125.993","BC","9.8","0",NA,"15.3","0","5.1","0","",,NA,"228.6","0",NA,"","15","",,NA,"255.5","0.0","1022795"
66 | "HERIOT BAY SE","50.099","-125.203","BC","9.6","3",NA,"19.0","3","3.5","3","0.0","3",NA,"115.0","3",NA,"0.0","14","","",NA,"235.2","0.0","1023462"
67 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","8.6","2","-0.2","19.5","2","-2.0","2","0.0","2",NA,"152.6","2",NA,"0.0","11","","",NA,"272.7","0.0","1024638"
68 | "NANAIMO A","49.054","-123.870","BC","9.6","0",NA,"19.5","0","-0.5","0","0.0","0",NA,"114.0","0",NA,"0.0","9","","",NA,"259.9","0.0","1025369"
69 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"0.0","0","0.0","93.7","0","94.0","0.0","8","","",NA,"","","10253G0"
70 | "PINE ISLAND","50.976","-127.728","BC","9.9","1","0.1","17.5","1","5.5","1","0.0","1",NA,"301.6","1",NA,"0.0","17","","",NA,"242.1","0.0","1026170"
71 | "PORT HARDY A","50.681","-127.367","BC","8.3","0",NA,"15.9","0","-0.6","0","0.0","0",NA,"253.8","0",NA,"","17","",,NA,"301.3","0.0","1026271"
72 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","9.1","0",NA,"18.2","0","0.7","0","",,NA,"91.0","0",NA,"","11","",,NA,"275.3","0.0","1026562"
73 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","9.5","0","0.3","19.0","0","2.0","0","0.0","0","0.0","141.2","0","96.0","0.0","12","","",NA,"262.6","0.0","1026565"
74 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","9.4","1","0.2","20.5","1","-0.5","1","0.0","1",NA,"165.4","1",NA,"","16","","",NA,"258.3","0.0","1026639"
75 | "SISTERS ISLAND","49.487","-124.435","BC","11.5","0",NA,"17.2","0","7.7","0","",,NA,"",,NA,"","","",,NA,"201.0","0.0","1027403"
76 | "ENTRANCE ISLAND","49.209","-123.809","BC","11.0","1",NA,"17.0","1","7.0","1","0.0","1",NA,"45.4","1",NA,"0.0","5","","",NA,"210.4","0.0","102BFHH"
77 | "CAPE BEALE LIGHT","48.786","-125.216","BC","11.1","0","0.6","18.5","0","5.5","0","0.0","0","0.0","288.8","0","102.0","0.0","15","","",NA,"213.0","0.0","1031316"
78 | "ESTEVAN POINT","49.383","-126.543","BC","10.8","0","0.5","17.5","0","3.5","0","0.0","0","0.0","279.6","0","85.0","0.0","17","","",NA,"222.9","0.0","1032730"
79 | "ESTEVAN POINT CS","49.383","-126.543","BC","10.4","11",NA,"17.1","11","3.3","10","",,NA,"195.3","11",NA,"","12","",,NA,"152.7","0.0","1032731"
80 | "LENNARD ISLAND","49.111","-125.923","BC","9.8","0",NA,"17.0","0","4.0","0","0.0","0","0.0","249.0","0","77.0","0.0","16","","",NA,"252.7","0.0","1034600"
81 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","10.0","0","-0.3","21.0","0","0.0","0","0.0","0","0.0","582.1","0","150.0","0.0","16","","",NA,"248.6","0.0","1035612"
82 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","11.2","2","0.3","20.0","2","4.0","2","0.0","2",NA,"318.4","2",NA,"0.0","13","","",NA,"198.6","0.0","1035614"
83 | "PACHENA POINT","48.723","-125.097","BC","9.8","2","-0.2","17.0","2","2.0","2","0.0","2",NA,"251.7","2",NA,"0.0","14","","",NA,"237.4","0.0","1035940"
84 | "PORT ALBERNI COX LAKE","49.202","-124.752","BC","10.2","15","0.3","19.5","15","1.0","15","0.0","15",NA,"208.6","15",NA,"0.0","9","","",NA,"124.9","0.0","1036208"
85 | "QUATSINO","50.534","-127.653","BC","9.5","4","-0.4","17.0","4","3.0","4","0.0","4",NA,"198.2","4",NA,"0.0","15","","",NA,"230.4","0.0","1036570"
86 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","8.4","29",NA,"12.2","29","4.3","29","",,NA,"26.3","29",NA,"","2","",,NA,"19.2","0.0","1036B06"
87 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","10.2","1",NA,"13.1","1","6.9","0","",,NA,"159.4","1",NA,"","16","",,NA,"235.2","0.0","1037090"
88 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","10.8","1",NA,"19.0","1","5.7","0","",,NA,"114.4","1",NA,"","15","",,NA,"216.1","0.0","1037553"
89 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","9.9","11",NA,"19.5","11","0.0","11","0.0","11",NA,"563.4","11",NA,"0.0","12","","",NA,"162.2","0.0","1037899"
90 | "TOFINO A","49.082","-125.773","BC","9.9","3","0.0","18.0","3","2.0","3","0.0","3",NA,"255.0","3",NA,"0.0","12","","",NA,"226.6","0.0","1038205"
91 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","10.2","0","0.0","19.5","0","1.5","0","0.0","0","0.0","314.4","0","91.0","0.0","14","","",NA,"241.5","0.0","1038332"
92 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","10.5","1",NA,"22.0","1","1.5","1","0.0","1",NA,"517.9","1",NA,"0.0","16","","",NA,"224.6","0.0","1039035"
93 | "BOWEN ISLAND SUNSET PARK","49.360","-123.402","BC","",,NA,"",,"",,"0.0","22",NA,"111.4","22",NA,"","9","","",NA,"","","104091B"
94 | "GIBSONS GOWER POINT","49.386","-123.541","BC","10.6","0","0.1","18.0","0","4.5","0","0.0","0","0.0","99.8","0","71.0","0.0","12","","",NA,"230.0","0.0","1043152"
95 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","11.1","0","0.3","17.5","0","6.0","0","0.0","0","0.0","83.4","0","79.0","0.0","10","","",NA,"213.0","0.0","1045100"
96 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","11.3","0",NA,"19.4","0","6.7","0","",,NA,"101.8","0",NA,"","12","",,NA,"208.3","0.0","10459NN"
97 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"0.0","0",NA,"72.3","0",NA,"0.0","11","","",NA,"","","1046115"
98 | "PORT MELLON","49.526","-123.496","BC","10.0","0",NA,"21.0","0","3.1","0","",,NA,"241.1","0",NA,"","14","",,NA,"247.0","0.0","1046332"
99 | "POWELL RIVER A","49.834","-124.500","BC","8.6","0","-0.7","18.0","0","0.0","0","0.0","0","0.0","78.2","0","62.0","0.0","10","","",NA,"290.5","0.0","1046391"
100 | "POWELL RIVER","49.835","-124.497","BC","8.7","0",NA,"18.1","0","0.5","0","",,NA,"",,NA,"","","",,NA,"287.4","0.0","1046392"
101 | "SECHELT AUT","49.458","-123.715","BC","9.6","0",NA,"17.9","0","2.2","0","",,NA,"70.4","0",NA,"","12","",,NA,"261.0","0.0","1047172"
102 | "SQUAMISH AIRPORT","49.783","-123.161","BC","9.5","0",NA,"20.8","0","0.4","0","",,NA,"255.1","0",NA,"","12","",,NA,"262.1","0.0","10476F0"
103 | "WHISTLER","50.129","-122.955","BC","6.0","2","-0.7","18.5","2","-2.0","2","17.8","2",NA,"151.8","2",NA,"0.0","12","","",NA,"348.6","0.0","1048898"
104 | "CAPE ST JAMES","51.936","-131.016","BC","10.6","1",NA,"16.5","1","5.6","0","",,NA,"183.3","10",NA,"","18","",,NA,"222.3","0.0","1051351"
105 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","10.7","3",NA,"16.8","2","6.2","1","",,NA,"167.2","3",NA,"","15","",,NA,"205.7","0.0","1054222"
106 | "LANGARA","54.255","-133.058","BC","9.5","0","0.3","15.5","0","4.0","0","0.0","0","0.0","172.4","0","67.0","0.0","18","","",NA,"264.9","0.0","1054500"
107 | "ROSE SPIT (AUT)","54.159","-131.661","BC","9.4","0",NA,"15.0","0","0.9","0","",,NA,"191.3","0",NA,"","18","",,NA,"265.7","0.0","1056869"
108 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","9.7","4",NA,"16.1","4","2.1","0","",,NA,"167.1","4",NA,"","15","",,NA,"225.1","0.0","1057051"
109 | "SANDSPIT","53.254","-131.814","BC","10.3","5",NA,"16.4","5","3.5","5","",,NA,"142.8","5",NA,"","14","",,NA,"199.6","0.0","1057052"
110 | "ADDENBROKE ISLAND","51.604","-127.864","BC","10.0","0","0.4","16.5","0","4.0","0","0.0","0","0.0","633.2","0","147.0","0.0","20","","",NA,"248.9","0.0","1060080"
111 | "BELLA BELLA","52.185","-128.157","BC","",,NA,"",,"",,"",,NA,"350.4","1",NA,"","18","",,NA,"","","1060815"
112 | "BELLA COOLA A","52.388","-126.596","BC","8.7","0","0.4","19.0","0","-1.0","0","0.0","0","0.0","321.9","0","165.0","0.0","17","","",NA,"288.6","0.0","1060841"
113 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","8.4","2",NA,"18.6","2","-1.2","1","",,NA,"285.8","2",NA,"","15","",,NA,"278.4","0.0","1060844"
114 | "BOAT BLUFF","52.643","-128.524","BC","10.3","0","1.2","20.0","0","3.5","0","0.0","0","0.0","775.6","0","123.0","0.0","17","","",NA,"240.2","0.0","1060901"
115 | "BONILLA ISLAND","53.493","-130.638","BC","10.1","0","0.3","16.0","0","5.0","0","0.0","0","0.0","192.0","0","76.0","0.0","17","","",NA,"244.5","0.0","1060902"
116 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","9.8","2",NA,"16.1","2","5.4","1","",,NA,"112.2","2",NA,"","15","",,NA,"239.2","0.0","1060R0K"
117 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","9.7","2",NA,"18.6","1","4.1","1","",,NA,"812.6","2",NA,"","15","",,NA,"241.4","0.0","1061458"
118 | "CUMSHEWA ISLAND","53.030","-131.602","BC","10.5","2",NA,"17.2","2","5.6","1","",,NA,"94.6","2",NA,"","12","",,NA,"217.3","0.0","1062251"
119 | "DRYAD POINT","52.185","-128.112","BC","10.4","0","0.6","19.5","0","3.5","0","0.0","0","0.0","426.4","0","128.0","0.0","19","","",NA,"234.5","0.0","1062544"
120 | "EGG ISLAND","51.247","-127.835","BC","9.0","0","-0.3","14.0","0","4.0","0","0.0","0","0.0","377.2","0","115.0","0.0","15","","",NA,"278.7","0.0","1062646"
121 | "GREEN ISLAND","54.569","-130.708","BC","8.9","0","0.0","14.0","0","4.0","0","0.0","0","0.0","237.4","0","67.0","0.0","17","","",NA,"283.3","0.0","1063298"
122 | "GREY ISLET (AUT)","54.580","-130.698","BC","9.6","2",NA,"14.3","2","5.1","0","",,NA,"198.6","2",NA,"","16","",,NA,"243.6","0.0","1063303"
123 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","9.8","1",NA,"14.8","1","5.5","0","",,NA,"147.6","1",NA,"","15","",,NA,"244.6","0.0","1063461"
124 | "HOLLAND ROCK","54.172","-130.361","BC","9.1","0",NA,"16.9","0","4.5","0","",,NA,"173.2","0",NA,"","17","",,NA,"275.9","0.0","1063496"
125 | "IVORY ISLAND","52.270","-128.407","BC","10.4","0","0.6","20.5","0","4.0","0","0.0","0","0.0","365.6","0","103.0","0.0","18","","",NA,"237.0","0.0","1063690"
126 | "KEMANO","53.563","-127.943","BC","6.8","2","-0.4","19.0","1","-1.5","1","0.0","1",NA,"447.0","1",NA,"0.0","16","","",NA,"325.6","0.0","1064020"
127 | "KITIMAT TOWNSITE","54.054","-128.634","BC","6.2","6","-1.0","15.0","6","-5.0","6","9.0","6",NA,"394.6","6",NA,"0.0","14","","",NA,"294.9","0.0","1064320"
128 | "KITIMAT 2","54.010","-128.705","BC","6.8","4","-1.0","21.0","4","-1.0","4","8.0","4",NA,"477.6","4",NA,"0.0","17","","",NA,"301.4","0.0","1064321"
129 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","9.5","1",NA,"15.1","1","5.1","0","",,NA,"",,NA,"","","",,NA,"256.4","0.0","1064728"
130 | "MCINNES ISLAND","52.262","-128.719","BC","10.9","0","1.0","18.5","0","5.0","0","0.0","0","0.0","328.4","0","105.0","0.0","17","","",NA,"221.2","0.0","1065010"
131 | "PRINCE RUPERT","54.286","-130.445","BC","8.1","4",NA,"17.9","4","0.2","4","",,NA,"229.0","4",NA,"","16","",,NA,"267.4","0.0","1066482"
132 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"0.0","12",NA,"431.8","12",NA,"0.0","12","","",NA,"","","1066488"
133 | "TERRACE PCC","54.502","-128.625","BC","6.5","1","-0.7","17.0","1","-3.0","1","0.0","1",NA,"261.4","1",NA,"0.0","14","","",NA,"344.4","0.0","1068131"
134 | "TERRACE A","54.469","-128.578","BC","5.6","0",NA,"15.1","0","-2.5","0","2.2","1",NA,"309.7","0",NA,"","18","",,NA,"385.2","0.0","1068134"
135 | "TRIPLE ISLAND","54.295","-130.880","BC","9.8","0",NA,"14.0","0","6.0","0","0.0","0",NA,"139.0","0",NA,"0.0","14","","",NA,"253.3","0.0","1068250"
136 | "EQUITY SILVER","54.199","-126.277","BC","2.0","0","0.3","16.0","0","-6.5","0","68.8","0","221.0","132.6","0","188.0","0.0","13","","",NA,"497.1","0.0","1072692"
137 | "HOUSTON","54.396","-126.668","BC","4.0","7",NA,"19.0","7","-6.0","7","0.0","14",NA,"80.6","14",NA,"0.0","5","","",NA,"336.2","0.0","1073615"
138 | "SMITHERS","54.825","-127.183","BC","4.2","12",NA,"15.8","12","-5.7","12","",,NA,"110.7","12",NA,"","7","",,NA,"262.1","0.0","1077499"
139 | "SMITHERS A","54.825","-127.183","BC","4.0","0","-0.4","16.5","0","-5.5","0","10.4","0","121.0","132.4","0","204.0","0.0","9","","",NA,"435.3","0.0","1077500"
140 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","4.0","1",NA,"16.5","1","-4.8","0","",,NA,"129.0","1",NA,"1.0","11","",,NA,"420.0","0.0","1077501"
141 | "SUSKWA VALLEY","55.289","-127.171","BC","2.2","4","-2.0","15.0","4","-7.0","4","14.6","4",NA,"148.6","4",NA,"0.0","15","","",NA,"427.9","0.0","107G879"
142 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","5.5","1",NA,"17.0","1","-3.2","0","",,NA,"51.7","1",NA,"","10","",,NA,"373.8","0.0","1085836"
143 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","8.3","0",NA,"20.4","0","-2.2","0","",,NA,"116.6","0",NA,"","12","",,NA,"301.2","0.0","1086082"
144 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","3.9","0",NA,"22.8","0","-11.4","0","",,NA,"36.9","0",NA,"","6","",,NA,"435.7","0.0","1086558"
145 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","5.1","0",NA,"21.1","0","-9.9","0","",,NA,"82.0","0",NA,"","9","",,NA,"400.3","0.0","1088015"
146 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","2.8","0",NA,"17.6","0","-9.3","0","",,NA,"69.8","0",NA,"","10","",,NA,"472.2","0.0","1091174"
147 | "FORT ST JAMES","54.455","-124.286","BC","4.5","14","0.2","16.5","14","-5.0","14","2.0","14",NA,"37.0","14",NA,"0.0","6","","",NA,"229.2","0.0","1092970"
148 | "FORT ST JAMES AUTO","54.455","-124.286","BC","5.3","0",NA,"16.9","0","-5.2","0","",,NA,"60.6","0",NA,"","9","",,NA,"395.2","0.0","1092975"
149 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","3.9","16",NA,"21.0","11","-6.0","12","22.6","11",NA,"63.2","11",NA,"0.0","8","","",NA,"211.4","0.0","1095018"
150 | "PRINCE GEORGE","53.884","-122.678","BC","5.0","12",NA,"17.9","12","-9.6","12","",,NA,"45.6","12",NA,"","10","",,NA,"247.5","0.0","1096439"
151 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","4.3","1",NA,"14.1","1","-9.9","0","",,NA,"49.8","3",NA,"","12","",,NA,"412.3","0.0","1096453"
152 | "PRINCE GEORGE STP","53.880","-122.768","BC","6.0","8","0.7","18.5","0","-3.0","8","2.0","0","45.0","53.0","0","88.0","0.0","14","","",NA,"274.9","0.0","1096468"
153 | "QUESNEL","53.026","-122.510","BC","5.6","10",NA,"19.1","10","-7.9","9","",,NA,"31.2","10",NA,"","5","",,NA,"259.5","0.0","1096629"
154 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","5.3","0",NA,"19.4","0","-8.0","0","",,NA,"54.6","0",NA,"","9","",,NA,"394.2","0.0","1096631"
155 | "SPOKIN LAKE 4E","52.184","-121.686","BC","2.3","0","-1.0","19.0","0","-13.0","0","9.6","0","88.0","59.2","0","120.0","0.0","9","","",NA,"486.0","0.0","1097646"
156 | "WILLIAMS LAKE A","52.183","-122.054","BC","4.1","0",NA,"18.3","0","-7.2","0","16.2","0",NA,"45.4","0",NA,"","10","",,NA,"430.7","0.0","1098941"
157 | "VANDERHOOF","54.033","-124.017","BC","5.1","0","0.0","20.0","0","-11.0","0","0.6","0","8.0","51.2","0","101.0","0.0","11","","",NA,"400.7","0.0","1098D90"
158 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","4.6","0",NA,"20.5","0","-6.5","0","8.0","0",NA,"34.5","0",NA,"0.0","6","","",NA,"414.7","0.0","109E7R6"
159 | "ABBOTSFORD A","49.025","-122.360","BC","10.2","1",NA,"20.3","0","1.1","1","0.0","0",NA,"186.6","0",NA,"","14","",,NA,"233.5","0.0","1100031"
160 | "AGASSIZ RCS","49.243","-121.760","BC","10.8","0","-0.4","20.8","0","2.6","0","",,NA,"253.3","0",NA,"","17","",,NA,"224.0","0.0","1100119"
161 | "AGASSIZ CDA","49.243","-121.760","BC","10.3","5","-0.6","20.0","3","3.0","2","0.0","2",NA,"236.5","2",NA,"0.0","16","","",NA,"199.8","0.0","1100120"
162 | "WHISTLER - NESTERS","50.129","-122.955","BC","6.1","0",NA,"18.7","0","-2.0","0","",,NA,"155.7","0",NA,"","10","",,NA,"370.4","0.0","1100875"
163 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","5.8","1",NA,"17.9","1","-1.0","0","",,NA,"143.5","1",NA,"","11","",,NA,"367.0","0.0","1100881"
164 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","11.0","15","1.4","18.0","15","5.0","15","0.0","15",NA,"31.8","15",NA,"0.0","4","","",NA,"112.7","0.0","1101158"
165 | "CALLAGHAN VALLEY","50.144","-123.111","BC","5.7","0",NA,"19.2","0","-1.2","0","",,NA,"208.3","0",NA,"","13","",,NA,"380.0","0.0","1101300"
166 | "CLOVERDALE EAST","49.109","-122.698","BC","11.4","0",NA,"21.5","0","2.5","0","0.0","0",NA,"166.1","0",NA,"0.0","11","","",NA,"205.0","0.0","1101708"
167 | "DELTA BURNS BOG","49.126","-123.002","BC","9.1","0",NA,"18.7","0","-1.2","0","",,NA,"115.3","0",NA,"","10","",,NA,"276.9","0.0","1102415"
168 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","9.5","1","-1.7","17.0","1","2.0","1","0.0","1",NA,"83.1","1",NA,"0.0","11","","",NA,"254.4","0.0","1102425"
169 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","10.7","1",NA,"20.5","1","1.5","1","0.0","1",NA,"193.2","1",NA,"0.0","13","","",NA,"219.9","0.0","1102912"
170 | "HANEY UBC RF ADMIN","49.264","-122.573","BC","9.6","16","-0.3","19.5","16","3.5","16","0.0","16",NA,"107.2","16",NA,"","6","","",NA,"125.5","0.0","1103332"
171 | "MISSION WEST ABBEY","49.153","-122.271","BC","10.7","0","0.2","19.5","0","4.5","0","0.0","0","0.0","256.8","0","135.0","0.0","15","","",NA,"224.9","0.0","1105192"
172 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"130.9","0",NA,"","11","",,NA,"","","1105210"
173 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","5.9","4","0.1","22.0","4","-3.0","4","0.0","4",NA,"292.5","4",NA,"0.0","14","","",NA,"325.9","0.0","1105658"
174 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","11",NA,"397.2","11",NA,"","8","","",NA,"","","1105669"
175 | "PITT MEADOWS CS","49.208","-122.690","BC","10.2","0",NA,"21.5","0","0.9","0","",,NA,"197.1","0",NA,"","12","",,NA,"242.6","0.0","1106178"
176 | "POINT ATKINSON","49.330","-123.265","BC","10.9","0",NA,"17.1","0","6.3","0","",,NA,"75.2","0",NA,"","13","",,NA,"221.5","0.0","1106200"
177 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","10.3","0","-0.1","20.0","0","4.0","0","0.0","0","0.0","238.3","0","117.0","0.0","12","","",NA,"237.5","0.0","1106CL2"
178 | "RICHMOND NATURE PARK","49.171","-123.093","BC","9.9","0","-0.4","19.5","0","0.0","0","0.0","0","0.0","152.7","0","120.0","0.0","14","","",NA,"252.1","0.0","1106PF7"
179 | "SANDHEADS CS","49.106","-123.303","BC","11.2","4",NA,"18.4","4","6.0","0","",,NA,"",,NA,"","","",,NA,"182.6","0.0","1107010"
180 | "SUMAS CANAL","49.113","-122.110","BC","11.2","21",NA,"22.0","14","5.5","15","0.0","14",NA,"187.0","14",NA,"0.0","10","","",NA,"68.4","0.0","1107785"
181 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","9.9","2",NA,"16.7","2","1.9","1","",,NA,"129.0","2",NA,"","11","",,NA,"234.1","0.0","1108380"
182 | "VANCOUVER INTL A","49.195","-123.184","BC","9.8","1",NA,"16.8","1","0.6","0","0.0","1",NA,"114.3","1",NA,"","12","",,NA,"246.7","0.0","1108395"
183 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","10.8","0",NA,"19.0","0","5.1","0","",,NA,"184.3","0",NA,"","12","",,NA,"221.9","0.0","1108446"
184 | "WEST VANCOUVER AUT","49.347","-123.193","BC","10.9","0",NA,"19.7","0","3.6","0","",,NA,"171.0","0",NA,"","14","",,NA,"220.2","0.0","1108824"
185 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","10.5","0",NA,"22.0","0","2.0","0","",,NA,"160.4","0",NA,"","12","",,NA,"231.9","0.0","1108910"
186 | "N VAN SEYMOUR HATCHERY","49.438","-122.967","BC","8.9","11","-0.6","19.0","10","1.0","11","0.0","10",NA,"242.4","10",NA,"","10","","",NA,"181.7","0.0","110N666"
187 | "HOPE A","49.368","-121.498","BC","10.5","10",NA,"21.6","10","2.9","10","",,NA,"196.1","10",NA,"","11","",,NA,"157.2","0.0","1113542"
188 | "HOPE AIRPORT","49.370","-121.493","BC","10.4","0",NA,"21.7","0","2.3","0","",,NA,"287.6","0",NA,"","14","",,NA,"236.8","0.0","1113543"
189 | "HOPE SLIDE","49.267","-121.233","BC","6.1","0","-0.4","18.0","0","-2.5","0","2.0","0","51.0","194.8","0","145.0","0.0","17","","",NA,"370.3","0.0","1113581"
190 | "LILLOOET","50.684","-121.934","BC","9.4","0",NA,"19.5","0","-1.0","0","",,NA,"",,NA,"","","",,NA,"266.8","0.0","1114619"
191 | "LYTTON A","50.224","-121.582","BC","10.0","14",NA,"19.3","14","0.7","13","",,NA,"56.7","14",NA,"","6","",,NA,"136.8","0.0","1114738"
192 | "LYTTON RCS","50.224","-121.582","BC","9.8","0",NA,"20.0","0","-1.0","0","",,NA,"51.7","0",NA,"","7","",,NA,"253.1","0.0","1114746"
193 | "JELLICOE","49.673","-120.333","BC","4.8","3",NA,"23.0","3","-7.5","3","8.0","3",NA,"53.2","3",NA,"0.0","10","","",NA,"369.6","0.0","1123721"
194 | "KELOWNA","49.957","-119.378","BC","6.6","10",NA,"18.1","10","-5.9","9","",,NA,"11.1","10",NA,"","4","",,NA,"240.0","0.0","1123939"
195 | "KELOWNA UBCO","49.941","-119.400","BC","7.8","0",NA,"18.5","0","-2.9","0","",,NA,"21.6","0",NA,"","6","",,NA,"317.7","0.0","1123996"
196 | "MERRITT","50.113","-120.778","BC","6.8","0",NA,"21.8","0","-7.8","0","",,NA,"37.2","16",NA,"","5","",,NA,"347.9","0.0","1125073"
197 | "MERRITT STP","50.114","-120.801","BC","7.3","0","-0.3","20.5","0","-5.0","0","0.0","0","0.0","56.6","0","205.0","0.0","8","","",NA,"331.3","0.0","1125079"
198 | "OKANAGAN CENTRE","50.056","-119.445","BC","9.3","0","0.2","17.0","0","0.5","0","0.0","0","0.0","39.4","0","124.0","0.0","9","","",NA,"270.2","0.0","1125700"
199 | "OLIVER STP","49.179","-119.545","BC","9.6","12","-0.1","20.0","11","-2.0","12","0.0","11",NA,"1.8","11",NA,"0.0","0","","",NA,"158.7","0.0","1125766"
200 | "OSOYOOS CS","49.028","-119.441","BC","9.2","0","-0.8","20.4","0","-2.7","0","",,NA,"6.2","0",NA,"","1","",,NA,"273.1","0.0","1125852"
201 | "PEACHLAND","49.783","-119.717","BC","9.2","0","-0.4","16.5","0","0.5","0","0.0","0","0.0","16.8","0","59.0","0.0","7","","",NA,"273.6","0.0","1126070"
202 | "PENTICTON A","49.463","-119.602","BC","8.1","0",NA,"19.2","0","-4.8","0","0.0","0",NA,"14.2","0",NA,"","4","",,NA,"306.8","0.0","1126146"
203 | "PRINCETON A","49.468","-120.513","BC","5.6","0","-1.2","21.0","0","-6.5","0","0.0","0","0.0","38.0","0","146.0","0.0","7","","",NA,"385.7","0.0","1126510"
204 | "VERNON AUTO","50.223","-119.194","BC","7.3","0",NA,"18.4","0","-2.7","0","",,NA,"35.4","0",NA,"","9","",,NA,"332.9","0.0","1128582"
205 | "VERNON NORTH","50.344","-119.271","BC","6.9","0","-0.9","17.5","0","-2.0","0","0.0","0","0.0","40.4","0","97.0","0.0","9","","",NA,"343.3","0.0","1128583"
206 | "PRINCETON CS","49.465","-120.510","BC","5.6","3",NA,"21.0","3","-6.5","1","",,NA,"37.7","3",NA,"","8","",,NA,"348.3","0.0","112FN0M"
207 | "SUMMERLAND CS","49.563","-119.649","BC","8.3","0","-0.7","17.7","0","-1.8","0","",,NA,"10.8","0",NA,"","3","",,NA,"300.8","0.0","112G8L1"
208 | "MIDWAY","49.004","-118.772","BC","6.2","0","-1.1","23.0","0","-7.5","0","0.0","0","0.0","25.0","0","102.0","0.0","5","","",NA,"367.3","0.0","1135126"
209 | "BILLINGS","49.017","-118.228","BC","6.5","5","-1.7","19.5","5","-3.0","5","0.0","5",NA,"22.0","5",NA,"0.0","4","","",NA,"300.0","0.0","1140876"
210 | "CASTLEGAR A","49.296","-117.633","BC","7.6","0","-0.4","19.0","0","-3.5","0","0.6","0","32.0","60.4","0","118.0","0.0","8","","",NA,"322.2","0.0","1141455"
211 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","8.0","9","-0.4","17.5","4","0.0","5","0.0","4",NA,"37.4","4",NA,"0.0","8","","",NA,"219.3","0.0","1141457"
212 | "DUNCAN LAKE DAM","50.239","-116.972","BC","5.6","0","-0.8","17.0","0","-5.0","0","0.0","0","0.0","104.4","0","158.0","0.0","14","","",NA,"383.0","0.0","1142574"
213 | "KASLO","49.913","-116.921","BC","7.0","0","-0.4","20.0","0","-3.0","0","0.0","0","0.0","85.4","0","130.0","0.0","11","","",NA,"342.5","0.0","1143900"
214 | "NAKUSP CS","50.269","-117.817","BC","7.0","0",NA,"17.0","0","-3.1","0","",,NA,"77.9","0",NA,"","13","",,NA,"339.9","0.0","1145297"
215 | "NELSON NE","49.586","-117.206","BC","8.0","0",NA,"19.0","0","-2.0","0","0.0","0",NA,"78.2","0",NA,"0.0","10","","",NA,"310.9","0.0","1145442"
216 | "NEW DENVER","49.996","-117.370","BC","7.1","0","-0.4","18.0","0","-2.5","0","1.0","0","370.0","89.0","0","127.0","0.0","10","","",NA,"336.8","0.0","1145460"
217 | "NELSON CS","49.491","-117.305","BC","8.1","0",NA,"21.2","0","-1.6","0","",,NA,"58.0","0",NA,"","6","",,NA,"308.2","0.0","1145M29"
218 | "WARFIELD RCS","49.112","-117.739","BC","7.4","0",NA,"20.0","0","-2.4","0","",,NA,"52.8","0",NA,"","6","",,NA,"330.0","0.0","1148705"
219 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","7.7","0",NA,"18.6","0","-2.0","0","",,NA,"51.9","0",NA,"","6","",,NA,"319.6","0.0","114B1F0"
220 | "NELSON RIXEN CREEK","49.512","-117.399","BC","6.7","1",NA,"20.5","1","-3.5","1","2.4","1",NA,"73.8","1",NA,"0.0","8","","",NA,"340.0","0.0","114EMDM"
221 | "CRANBROOK A","49.612","-115.782","BC","4.7","2",NA,"18.6","0","-8.2","2","0.8","0",NA,"25.0","0",NA,"","8","",,NA,"385.5","0.0","1152105"
222 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","5.0","0",NA,"18.5","0","-7.9","0","",,NA,"17.9","0",NA,"","6","",,NA,"404.1","0.0","1152106"
223 | "FERNIE","49.489","-115.073","BC","5.7","12","0.3","19.0","12","-8.0","12","4.0","12",NA,"36.0","12",NA,"0.0","8","","",NA,"233.4","0.0","1152850"
224 | "FT STEELE DANDY CRK","49.524","-115.461","BC","2.7","27",NA,"15.0","22","-8.5","23","2.0","22",NA,"23.2","22",NA,"0.0","4","","",NA,"61.3","0.0","1153034"
225 | "KIMBERLEY PCC","49.632","-115.962","BC","5.5","14","-0.2","18.5","14","-6.5","14","10.0","14",NA,"27.0","14",NA,"0.0","5","","",NA,"213.3","0.0","1154203"
226 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","3.4","13","-1.7","14.0","13","-6.0","13","11.0","13",NA,"30.8","13",NA,"0.0","4","","",NA,"263.3","0.0","1154410"
227 | "SPARWOOD","49.745","-114.883","BC","4.4","0","-0.4","16.5","0","-8.0","0","8.0","0","71.0","83.2","0","170.0","0.0","10","","",NA,"421.9","0.0","1157630"
228 | "SPARWOOD CS","49.745","-114.884","BC","4.3","0",NA,"16.7","0","-8.1","0","",,NA,"49.0","20",NA,"","5","",,NA,"425.9","0.0","1157631"
229 | "WASA","49.807","-115.631","BC","5.3","0","-0.4","17.0","0","-6.0","0","6.6","0","263.0","34.8","0","137.0","0.0","7","","",NA,"393.3","0.0","1158730"
230 | "ASHCROFT","50.708","-121.281","BC","8.6","0",NA,"20.1","0","-1.7","0","",,NA,"20.8","0",NA,"","7","",,NA,"291.8","0.0","1160515"
231 | "BLUE RIVER A","52.129","-119.290","BC","3.8","0","-0.7","18.0","0","-8.0","0","20.2","0","203.0","104.2","0","102.0","0.0","15","","",NA,"439.8","0.0","1160899"
232 | "BLUE RIVER CS","52.129","-119.290","BC","3.7","0",NA,"18.0","0","-8.1","0","",,NA,"99.6","0",NA,"","15","",,NA,"443.7","0.0","1160H99"
233 | "CLEARWATER AUTO","51.653","-120.082","BC","5.3","0",NA,"18.6","0","-4.9","0","",,NA,"52.8","0",NA,"2.0","12","",,NA,"393.2","0.0","1161650"
234 | "CLINTON A","51.266","-121.685","BC","2.7","12",NA,"17.2","12","-11.0","12","",,NA,"13.9","12",NA,"","4","",,NA,"291.2","0.0","1161662"
235 | "CLINTON RCS","51.144","-121.505","BC","3.6","0",NA,"16.5","0","-7.1","0","",,NA,"30.4","0",NA,"","7","",,NA,"446.4","0.0","1161663"
236 | "CRISS CREEK","51.030","-120.728","BC","2.8","0","-0.5","19.0","0","-10.0","0","24.2","0","227.0","50.4","0","148.0","0.0","9","","",NA,"470.5","0.0","1162177"
237 | "DARFIELD","51.292","-120.183","BC","6.0","4","-0.4","17.5","2","-4.0","2","0.0","1",NA,"41.1","1",NA,"0.0","10","","",NA,"324.2","0.0","1162265"
238 | "KAMLOOPS A","50.703","-120.449","BC","7.8","0",NA,"19.2","0","-4.9","0","0.0","0",NA,"26.8","0",NA,"","8","",,NA,"316.9","0.0","1163781"
239 | "KAMLOOPS AUT","50.702","-120.442","BC","7.8","0",NA,"18.9","0","-4.5","0","",,NA,"25.1","0",NA,"","5","",,NA,"315.1","0.0","1163842"
240 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","3.4","0",NA,"16.0","0","-8.0","0","10.2","0",NA,"34.0","0",NA,"0.0","8","","",NA,"452.7","0.0","1165793"
241 | "RED LAKE","50.935","-120.800","BC","3.9","0","-0.6","17.0","0","-6.0","0","31.6","0","266.0","62.8","0","177.0","0.0","10","","",NA,"436.5","0.0","1166658"
242 | "SILVER CREEK","50.545","-119.350","BC","6.0","0","-0.7","17.5","0","-6.0","0","0.0","0","0.0","35.9","0","73.0","0.0","10","","",NA,"372.0","0.0","1167337"
243 | "VAVENBY","51.576","-119.778","BC","5.2","0","-0.5","16.0","0","-5.5","0","0.0","0","0.0","52.6","0","122.0","0.0","9","","",NA,"397.8","0.0","1168520"
244 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","6.3","4",NA,"15.0","4","-3.0","4","0.0","4",NA,"22.4","4",NA,"0.0","7","","",NA,"314.7","0.0","116C8P0"
245 | "SALMON ARM CS","50.703","-119.291","BC","6.8","0","-0.9","17.3","0","-4.0","0","",,NA,"42.2","0",NA,"","8","",,NA,"347.0","0.0","116FRMN"
246 | "GOLDEN A","51.299","-116.982","BC","4.7","0","-0.3","15.5","0","-6.5","0","12.8","0","459.0","49.6","0","142.0","0.0","11","","",NA,"413.7","0.0","1173210"
247 | "GOLDEN AIRPORT","51.300","-116.984","BC","4.4","0",NA,"16.4","0","-6.3","0","",,NA,"34.2","0",NA,"","8","",,NA,"422.4","0.0","1173220"
248 | "GOLDSTREAM RIVER","51.630","-118.425","BC","4.4","0","-0.2","15.0","0","-3.0","0","6.6","0","72.0","105.6","0","100.0","0.0","19","","",NA,"421.5","0.0","1173242"
249 | "MICA DAM","52.053","-118.585","BC","4.8","3","-0.4","14.0","2","-3.0","1","11.0","2",NA,"207.0","2",NA,"0.0","16","","",NA,"369.3","0.0","1175122"
250 | "REVELSTOKE A","50.967","-118.183","BC","6.7","7",NA,"16.9","7","-2.3","6","",,NA,"55.6","7",NA,"","9","",,NA,"271.5","0.0","1176745"
251 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","6.6","0",NA,"16.7","0","-2.9","0","",,NA,"59.4","0",NA,"0.0","13","",,NA,"354.7","0.0","1176755"
252 | "YOHO PARK","51.443","-116.345","BC","0.8","1",NA,"15.4","1","-11.9","0","",,NA,"84.7","1",NA,"7.0","13","",,NA,"515.0","0.0","11790J1"
253 | "CHETWYND A","55.687","-121.627","BC","4.9","0","0.9","20.5","0","-7.0","0","19.0","0","99.0","75.6","0","260.0","0.0","8","","",NA,"405.2","0.0","1181508"
254 | "DAWSON CREEK A","55.742","-120.183","BC","5.1","4",NA,"21.9","4","-10.3","4","",,NA,"19.3","12",NA,"","1","",,NA,"347.1","0.0","1182289"
255 | "FORT ST. JOHN A","56.238","-120.740","BC","3.7","0",NA,"20.0","0","-8.3","0","59.3","0",NA,"79.6","0",NA,"0.0","9","",,NA,"441.9","0.0","1183001"
256 | "MACKENZIE","55.299","-123.133","BC","3.7","8",NA,"16.4","8","-5.8","8","",,NA,"55.2","8",NA,"","7","",,NA,"327.8","0.0","1184791"
257 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","3.8","0",NA,"16.6","0","-5.9","0","",,NA,"57.6","0",NA,"","10","",,NA,"439.7","0.0","1184793"
258 | "DEASE LAKE A","58.422","-130.031","BC","0.7","12",NA,"12.6","12","-8.1","12","",,NA,"9.9","12",NA,"","2","",,NA,"328.2","0.0","1192341"
259 | "FORT NELSON A","58.836","-122.597","BC","2.9","0",NA,"21.5","0","-7.8","0","15.7","0",NA,"49.1","0",NA,"1.0","10","",,NA,"466.6","0.0","1192946"
260 | "FORT NELSON","58.841","-122.574","BC","3.3","0",NA,"22.2","0","-6.2","0","",,NA,"21.6","0",NA,"0.0","7","",,NA,"454.4","0.0","1192948"
261 | "DEASE LAKE (AUT)","58.426","-130.025","BC","0.8","0",NA,"15.8","0","-8.5","0","",,NA,"25.1","0",NA,"3.0","9","",,NA,"533.8","0.0","119BLM0"
262 | "ATLIN","59.567","-133.700","BC","3.4","0","0.8","16.0","0","-6.5","0","0.0","0","0.0","5.2","0","14.0","0.0","2","","",NA,"453.0","0.0","1200560"
263 | "PLEASANT CAMP","59.450","-136.367","BC","3.0","0","0.1","13.5","0","-5.0","0","4.0","0","11.0","101.6","0","54.0","0.0","16","","",NA,"465.7","0.0","1206197"
264 |
--------------------------------------------------------------------------------
/data/eng-climate-summaries-British Columbia-12,2017.csv:
--------------------------------------------------------------------------------
1 | "Environment and Climate Change Canada"
2 | "Monthly Values for December - 2017"
3 |
4 | "Legend"
5 | "Stn_Name","Station Name"
6 | "Lat","Latitude (North + , degrees)"
7 | "Long","Longitude (West - , degrees)"
8 | "Prov","Province"
9 | "Tm","Mean Temperature (°C)"
10 | "DwTm","Days without Valid Mean Temperature"
11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)"
12 | "Tx","Highest Monthly Maximum Temperature (°C)"
13 | "DwTx","Days without Valid Maximum Temperature"
14 | "Tn","Lowest Monthly Minimum Temperature (°C)"
15 | "DwTn","Days without Valid Minimum Temperature"
16 | "S","Snowfall (cm)"
17 | "DwS","Days without Valid Snowfall"
18 | "S%N","Percent of Normal (1981-2010) Snowfall"
19 | "P","Total Precipitation (mm)"
20 | "DwP","Days without Valid Precipitation"
21 | "P%N","Percent of Normal (1981-2010) Precipitation"
22 | "S_G","Snow on the ground at the end of the month (cm)"
23 | "Pd","Number of days with Precipitation 1.0 mm or more"
24 | "BS","Bright Sunshine (hours)"
25 | "DwBS","Days without Valid Bright Sunshine"
26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine"
27 | "HDD","Degree Days below 18 °C"
28 | "CDD","Degree Days above 18 °C"
29 | "Clim_ID","Climate Identifier"
30 | "NA","Not Available"
31 |
32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID"
33 | "CHEMAINUS","48.935","-123.742","BC","3.0","0",NA,"8.0","0","-3.5","0","34.0","0",NA,"175.4","0",NA,"1.0","10","","",NA,"463.6","0.0","1011500"
34 | "COWICHAN LAKE FORESTRY","48.824","-124.133","BC","1.1","0","-1.8","11.0","0","-8.5","0","18.8","0","95.0","135.6","0","40.0","6.0","12","","",NA,"523.7","0.0","1012040"
35 | "LAKE COWICHAN","48.829","-124.052","BC","1.7","17","-0.9","10.5","13","-8.0","12","23.4","27",NA,"119.6","19",NA,"","8","","",NA,"228.9","0.0","1012055"
36 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"10.0","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475"
37 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","4.9","0",NA,"10.8","0","-0.6","0","",,NA,"105.8","3",NA,"","8","",,NA,"404.7","0.0","1012710"
38 | "GALIANO NORTH","48.985","-123.573","BC","4.7","11",NA,"9.0","11","0.5","11","5.0","11",NA,"98.2","11",NA,"0.0","7","","",NA,"266.4","0.0","10130MN"
39 | "MALAHAT","48.575","-123.530","BC","2.5","0",NA,"9.1","0","-5.1","0","",,NA,"70.8","15",NA,"","7","",,NA,"479.6","0.0","1014820"
40 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"29.0","5",NA,"109.0","5",NA,"","9","","",NA,"","","1015105"
41 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"15.8","0","167.0","139.6","0","79.0","0.0","12","","",NA,"","","1015628"
42 | "NORTH COWICHAN","48.824","-123.719","BC","2.4","0",NA,"11.0","0","-7.9","0","",,NA,"47.2","13",NA,"0.0","5","",,NA,"482.7","0.0","1015630"
43 | "NORTH PENDER ISLAND","48.764","-123.287","BC","3.8","3",NA,"9.5","3","-2.5","3","3.0","3",NA,"115.0","3",NA,"0.0","11","","",NA,"396.4","0.0","1015638"
44 | "RACE ROCKS","48.298","-123.531","BC","5.8","0",NA,"12.1","0","-0.1","0","",,NA,"",,NA,"","","",,NA,"379.3","0.0","1016640"
45 | "SAANICHTON CDA","48.622","-123.419","BC","3.6","10","-0.8","10.5","6","-3.0","6","4.0","6",NA,"120.2","6",NA,"0.0","11","","",NA,"301.8","0.0","1016940"
46 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","3.4","2","-0.8","8.0","2","-3.0","2","7.8","2",NA,"108.2","2",NA,"0.0","9","","",NA,"424.6","0.0","1016995"
47 | "SAANICHTON MT NEWTON","48.598","-123.427","BC","",,NA,"",,"",,"5.6","23",NA,"89.2","23",NA,"0.0","8","","",NA,"","","1016RM0"
48 | "SATURNA CAPMON CS","48.775","-123.128","BC","2.9","0",NA,"8.3","0","-2.4","0","",,NA,"151.8","0",NA,"0.0","11","",,NA,"466.9","0.0","1017099"
49 | "SATURNA ISLAND CS","48.784","-123.045","BC","4.5","0",NA,"9.4","0","0.3","0","",,NA,"112.0","2",NA,"","9","",,NA,"417.1","0.0","1017101"
50 | "SHAWNIGAN LAKE","48.647","-123.626","BC","2.7","0","-0.3","10.5","0","-6.0","0","37.0","0","248.0","117.2","0","60.0","10.0","11","","",NA,"474.2","0.0","1017230"
51 | "SHERINGHAM POINT","48.377","-123.921","BC","5.9","0",NA,"12.0","0","-0.3","0","",,NA,"142.8","2",NA,"","11","",,NA,"374.2","0.0","1017254"
52 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","4.2","0",NA,"9.4","0","-2.3","0","",,NA,"122.9","0",NA,"","12","",,NA,"426.9","0.0","1018598"
53 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"21.6","3",NA,"132.8","3",NA,"","11","","",NA,"","","1018605"
54 | "VICTORIA GONZALES CS","48.413","-123.325","BC","4.7","0",NA,"10.1","0","-1.5","0","",,NA,"102.6","4",NA,"","9","",,NA,"412.7","0.0","1018611"
55 | "VICTORIA INTL A","48.647","-123.426","BC","3.3","0",NA,"11.3","0","-4.4","0","10.1","0",NA,"131.3","0",NA,"","12","",,NA,"454.3","0.0","1018621"
56 | "WILLIAM HEAD","48.340","-123.539","BC","5.9","2","0.5","11.0","2","0.0","2","1.0","2",NA,"85.4","2",NA,"0.0","11","","",NA,"350.9","0.0","1018935"
57 | "BALLENAS ISLAND","49.350","-124.160","BC","4.2","0",NA,"8.7","0","-0.7","0","",,NA,"61.2","3",NA,"","9","",,NA,"427.6","0.0","1020590"
58 | "CAMPBELL RIVER A","49.952","-125.273","BC","0.8","2","-1.3","9.0","2","-10.5","2","33.8","2",NA,"107.8","2",NA,"0.0","12","","",NA,"498.6","0.0","1021261"
59 | "CAPE MUDGE","49.998","-125.195","BC","3.2","0","-0.6","10.0","0","-2.5","0","16.4","0","112.0","97.8","0","42.0","2.0","12","","",NA,"460.3","0.0","1021330"
60 | "CHROME ISLAND","49.472","-124.683","BC","3.6","0",NA,"10.0","0","-2.0","0","11.2","0",NA,"94.4","0",NA,"0.0","11","","",NA,"447.0","0.0","1021500"
61 | "COMOX A","49.717","-124.900","BC","2.4","0","-1.0","8.9","0","-5.2","0","11.4","0","61.0","91.2","0","49.0","2.0","11","",,NA,"482.1","0.0","1021830"
62 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","1.6","0",NA,"9.5","0","-6.5","0","11.2","0",NA,"91.3","0",NA,"10.0","12","","",NA,"506.9","0.0","1021960"
63 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","1.9","20",NA,"8.0","20","-3.0","19","0.0","20",NA,"14.2","20",NA,"","2","","",NA,"176.7","0.0","1021989"
64 | "ENTRANCE ISLAND","49.209","-123.811","BC","3.8","9",NA,"8.4","9","-0.2","8","",,NA,"30.0","12",NA,"","4","",,NA,"311.4","0.0","1022689"
65 | "FANNY ISLAND","50.454","-125.993","BC","4.1","0",NA,"10.7","0","-2.8","0","",,NA,"73.2","6",NA,"","10","",,NA,"430.7","0.0","1022795"
66 | "HERIOT BAY SE","50.099","-125.203","BC","2.2","4",NA,"8.0","4","-4.0","4","17.2","4",NA,"59.4","4",NA,"10.0","7","","",NA,"427.0","0.0","1023462"
67 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","0.7","18","-2.3","7.0","18","-7.5","18","9.0","18",NA,"24.0","18",NA,"","4","","",NA,"225.2","0.0","1024638"
68 | "NANAIMO A","49.054","-123.870","BC","1.8","2",NA,"10.0","2","-7.5","2","40.8","2",NA,"111.6","2",NA,"9.0","9","","",NA,"469.3","0.0","1025369"
69 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"4.2","0","44.0","74.7","0","42.0","0.0","9","","",NA,"","","10253G0"
70 | "PINE ISLAND","50.976","-127.728","BC","5.9","1","0.2","12.5","1","1.5","1","0.0","1",NA,"115.6","1",NA,"0.0","14","","",NA,"362.3","0.0","1026170"
71 | "PORT HARDY A","50.681","-127.367","BC","3.4","0",NA,"13.3","0","-5.0","0","12.4","1",NA,"95.4","0",NA,"","19","",,NA,"453.0","0.0","1026271"
72 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","2.0","0",NA,"9.1","0","-6.5","0","",,NA,"113.7","0",NA,"","10","",,NA,"496.4","0.0","1026562"
73 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","2.7","6","-0.7","9.0","6","-4.5","6","9.6","6",NA,"94.3","6",NA,"0.0","11","","",NA,"382.3","0.0","1026565"
74 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","1.4","1","-1.2","9.0","1","-6.5","1","18.6","1",NA,"70.0","1",NA,"","10","","",NA,"498.7","0.0","1026639"
75 | "SISTERS ISLAND","49.487","-124.435","BC","4.7","0",NA,"11.4","0","-0.1","0","",,NA,"",,NA,"","","",,NA,"413.6","0.0","1027403"
76 | "ENTRANCE ISLAND","49.209","-123.809","BC","4.4","4",NA,"8.5","4","-0.5","4","0.0","4",NA,"80.2","4",NA,"","8","","",NA,"368.5","0.0","102BFHH"
77 | "CAPE BEALE LIGHT","48.786","-125.216","BC","5.9","0","0.1","13.0","0","-1.0","0","1.0","0","27.0","183.2","0","48.0","0.0","12","","",NA,"373.8","0.0","1031316"
78 | "ESTEVAN POINT","49.383","-126.543","BC","5.9","0","0.3","14.0","0","-2.0","0","0.0","0","0.0","130.6","0","30.0","0.0","14","","",NA,"374.5","0.0","1032730"
79 | "ESTEVAN POINT CS","49.383","-126.543","BC","5.5","0",NA,"13.1","0","-2.0","0","",,NA,"120.8","0",NA,"","13","",,NA,"389.0","0.0","1032731"
80 | "LENNARD ISLAND","49.111","-125.923","BC","5.5","0",NA,"13.5","0","-1.5","0","1.0","0","28.0","128.8","0","30.0","0.0","13","","",NA,"386.4","0.0","1034600"
81 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","2.8","1","-0.5","10.0","1","-5.0","1","4.0","1",NA,"231.7","1",NA,"","12","","",NA,"455.8","0.0","1035612"
82 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","5.8","1","0.5","14.5","1","1.5","1","0.0","1",NA,"124.8","1",NA,"","12","","",NA,"365.7","0.0","1035614"
83 | "PACHENA POINT","48.723","-125.097","BC","5.6","1","0.3","10.5","1","-1.0","1","3.8","1",NA,"204.0","1",NA,"0.0","11","","",NA,"372.6","0.0","1035940"
84 | "QUATSINO","50.534","-127.653","BC","3.8","1","-0.2","12.5","1","-2.5","1","3.2","1",NA,"120.4","1",NA,"0.0","17","","",NA,"426.9","0.0","1036570"
85 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","1.1","6",NA,"6.1","6","-6.2","5","",,NA,"84.2","6",NA,"0.0","9","",,NA,"422.0","0.0","1036B06"
86 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","6.4","4",NA,"12.1","4","1.4","0","",,NA,"116.6","4",NA,"","17","",,NA,"311.9","0.0","1037090"
87 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","6.5","4",NA,"13.5","4","1.8","0","",,NA,"93.8","4",NA,"","14","",,NA,"310.7","0.0","1037553"
88 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","3.8","13",NA,"10.0","13","-2.0","13","",,NA,"64.8","25",NA,"","5","","",NA,"255.0","0.0","1037899"
89 | "TOFINO A","49.082","-125.773","BC","4.5","0","-0.5","13.5","0","-3.5","0","0.0","0","0.0","145.8","0","33.0","0.0","11","","",NA,"418.3","0.0","1038205"
90 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","5.0","0","-0.5","15.0","0","-4.0","0","0.0","0","0.0","186.1","0","41.0","0.0","15","","",NA,"403.2","0.0","1038332"
91 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","3.4","0",NA,"16.5","0","-5.0","0","0.0","0",NA,"105.1","0",NA,"0.0","10","","",NA,"451.8","0.0","1039035"
92 | "BOWEN ISLAND SUNSET PARK","49.360","-123.402","BC","",,NA,"",,"",,"13.0","25",NA,"89.0","25",NA,"","6","","",NA,"","","104091B"
93 | "GIBSONS GOWER POINT","49.386","-123.541","BC","3.7","2","-0.5","9.0","2","-2.0","2","0.8","2",NA,"99.4","2",NA,"0.0","7","","",NA,"415.2","0.0","1043152"
94 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","4.2","0","-1.0","8.0","0","0.0","0","7.8","0","104.0","101.6","0","76.0","0.0","10","","",NA,"429.2","0.0","1045100"
95 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","4.7","0",NA,"10.9","0","-0.2","0","",,NA,"69.0","2",NA,"","9","",,NA,"413.2","0.0","10459NN"
96 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"14.2","0",NA,"101.2","0",NA,"3.0","12","","",NA,"","","1046115"
97 | "PORT MELLON","49.526","-123.496","BC","2.9","0",NA,"10.1","0","-4.2","0","",,NA,"222.5","0",NA,"5.0","10","",,NA,"467.0","0.0","1046332"
98 | "POWELL RIVER A","49.834","-124.500","BC","1.4","0","-1.8","7.5","0","-7.0","0","18.0","0","157.0","98.9","0","63.0","10.0","11","","",NA,"515.9","0.0","1046391"
99 | "POWELL RIVER","49.835","-124.497","BC","1.5","0",NA,"7.8","0","-6.6","0","",,NA,"",,NA,"5.0","","",,NA,"510.0","0.0","1046392"
100 | "SECHELT AUT","49.458","-123.715","BC","2.2","0",NA,"8.6","0","-4.8","0","",,NA,"120.7","0",NA,"2.0","10","",,NA,"490.9","0.0","1047172"
101 | "SQUAMISH AIRPORT","49.783","-123.161","BC","1.6","0",NA,"11.3","0","-6.5","0","",,NA,"141.7","0",NA,"44.0","8","",,NA,"509.3","0.0","10476F0"
102 | "WHISTLER","50.129","-122.955","BC","-3.7","0","-0.9","4.0","0","-13.0","0","82.4","0","72.0","76.7","0","50.0","72.0","10","","",NA,"674.1","0.0","1048898"
103 | "CAPE ST JAMES","51.936","-131.016","BC","5.9","12",NA,"10.3","12","0.7","0","",,NA,"",,NA,"","","",,NA,"230.7","0.0","1051351"
104 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","6.3","4",NA,"15.7","4","-0.8","0","",,NA,"88.2","6",NA,"","13","",,NA,"315.8","0.0","1054222"
105 | "LANGARA","54.255","-133.058","BC","4.7","0","0.4","10.5","0","-3.5","0","5.4","0","45.0","119.6","0","54.0","1.0","19","",,NA,"411.5","0.0","1054500"
106 | "ROSE SPIT (AUT)","54.159","-131.661","BC","4.5","0",NA,"10.4","0","-4.7","0","",,NA,"69.8","4",NA,"","16","",,NA,"417.3","0.0","1056869"
107 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","4.4","1",NA,"10.9","1","-2.6","0","",,NA,"47.3","1",NA,"","11","",,NA,"408.0","0.0","1057051"
108 | "SANDSPIT","53.254","-131.814","BC","4.9","15",NA,"9.9","15","-0.9","15","",,NA,"26.8","15",NA,"","7","",,NA,"210.4","0.0","1057052"
109 | "ADDENBROKE ISLAND","51.604","-127.864","BC","4.5","0","-0.2","17.5","0","-3.0","0","5.0","0","34.0","126.6","0","34.0","0.0","15","","",NA,"419.8","0.0","1060080"
110 | "BELLA BELLA","52.185","-128.157","BC","1.5","9",NA,"11.1","9","-12.8","9","",,NA,"132.1","9",NA,"","11","",,NA,"363.8","0.0","1060815"
111 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","-1.6","1",NA,"8.7","1","-12.4","0","",,NA,"40.0","1",NA,"5.0","9","",,NA,"588.7","0.0","1060844"
112 | "BOAT BLUFF","52.643","-128.524","BC","3.8","0","0.2","15.5","0","-4.0","0","21.2","0","97.0","253.2","0","40.0","12.0","16","","",NA,"439.5","0.0","1060901"
113 | "BONILLA ISLAND","53.493","-130.638","BC","5.6","0","0.3","15.0","0","-2.5","0","8.8","0","85.0","164.6","0","61.0","1.0","20","","",NA,"385.6","0.0","1060902"
114 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","5.3","4",NA,"15.2","4","-2.5","0","",,NA,"87.4","4",NA,"","13","",,NA,"342.3","0.0","1060R0K"
115 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","2.3","4",NA,"11.0","4","-5.5","0","",,NA,"109.6","14",NA,"","9","",,NA,"422.9","0.0","1061458"
116 | "CUMSHEWA ISLAND","53.030","-131.602","BC","5.5","4",NA,"10.7","4","-1.7","0","",,NA,"12.4","4",NA,"","5","",,NA,"338.0","0.0","1062251"
117 | "DRYAD POINT","52.185","-128.112","BC","4.2","0","-0.2","16.5","0","-3.0","0","21.0","0","198.0","131.6","0","48.0","0.0","15","","",NA,"426.5","0.0","1062544"
118 | "EGG ISLAND","51.247","-127.835","BC","6.5","19","1.8","16.0","19","1.0","19","0.0","19",NA,"24.0","19",NA,"","4","","",NA,"138.1","0.0","1062646"
119 | "GREY ISLET (AUT)","54.580","-130.698","BC","3.5","4",NA,"12.8","4","-5.1","0","",,NA,"92.4","13",NA,"","14","",,NA,"391.3","0.0","1063303"
120 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","6.1","0",NA,"12.3","0","1.3","0","",,NA,"70.6","0",NA,"","12","",,NA,"370.3","0.0","1063461"
121 | "HOLLAND ROCK","54.172","-130.361","BC","4.6","0",NA,"15.4","0","-3.8","0","",,NA,"54.2","10",NA,"","10","",,NA,"413.9","0.0","1063496"
122 | "IVORY ISLAND","52.270","-128.407","BC","4.3","0","-0.6","14.5","0","-4.0","0","17.2","0","115.0","127.0","0","39.0","9.0","14","","",NA,"425.1","0.0","1063690"
123 | "KEMANO","53.563","-127.943","BC","-2.2","0","-1.4","4.5","0","-14.0","0","13.6","0","21.0","73.5","0","26.0","20.0","11","","",NA,"625.9","0.0","1064020"
124 | "KITIMAT TOWNSITE","54.054","-128.634","BC","-0.6","18","0.2","5.0","18","-17.0","6","4.0","6",NA,"89.0","6",NA,"0.0","13","","",NA,"241.8","0.0","1064320"
125 | "KITIMAT 2","54.010","-128.705","BC","-2.2","7","-2.0","8.0","7","-15.0","7","1.0","7",NA,"89.3","7",NA,"0.0","10","","",NA,"484.6","0.0","1064321"
126 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","4.8","0",NA,"14.7","0","-4.1","0","",,NA,"",,NA,"","","",,NA,"410.2","0.0","1064728"
127 | "MCINNES ISLAND","52.262","-128.719","BC","5.4","0","0.4","16.0","0","-2.0","0","3.0","0","28.0","139.6","0","48.0","0.0","17","",,NA,"391.1","0.0","1065010"
128 | "PRINCE RUPERT","54.286","-130.445","BC","2.3","9",NA,"13.9","9","-9.6","9","",,NA,"76.1","9",NA,"","9","",,NA,"345.2","0.0","1066482"
129 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"4.0","23",NA,"91.6","23",NA,"","6","","",NA,"","","1066488"
130 | "TERRACE PCC","54.502","-128.625","BC","-1.8","2","-0.4","4.5","2","-14.5","2","4.0","2",NA,"28.4","2",NA,"3.0","7","","",NA,"573.5","0.0","1068131"
131 | "TERRACE A","54.469","-128.578","BC","-3.8","0",NA,"4.2","0","-15.3","0","9.2","0",NA,"31.3","0",NA,"0.0","9","",,NA,"675.3","0.0","1068134"
132 | "TRIPLE ISLAND","54.295","-130.880","BC","5.2","0",NA,"15.0","0","-4.0","0","0.0","0",NA,"61.2","0",NA,"0.0","13","","",NA,"395.8","0.0","1068250"
133 | "EQUITY SILVER","54.199","-126.277","BC","-10.2","0","-2.7","5.5","0","-30.0","0","22.8","0","41.0","22.8","0","40.0","0.0","7","","",NA,"874.1","0.0","1072692"
134 | "HOUSTON","54.396","-126.668","BC","-10.3","8",NA,"3.0","8","-28.0","8","4.0","17",NA,"4.0","17",NA,"33.0","2","","",NA,"650.7","0.0","1073615"
135 | "SMITHERS","54.825","-127.183","BC","-12.3","11",NA,"1.3","10","-28.8","11","",,NA,"1.4","10",NA,"","0","",,NA,"606.1","0.0","1077499"
136 | "SMITHERS A","54.825","-127.183","BC","-9.2","0","-2.0","2.0","0","-29.5","0","15.4","0","34.0","9.2","0","22.0","36.0","5","","",NA,"842.7","0.0","1077500"
137 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","-10.1","0",NA,"1.4","0","-30.9","0","",,NA,"1.6","30",NA,"33.0","1","",,NA,"870.2","0.0","1077501"
138 | "SUSKWA VALLEY","55.289","-127.171","BC","-9.2","1","-4.1","1.5","1","-24.5","1","22.6","1",NA,"25.8","1",NA,"34.0","8","","",NA,"817.2","0.0","107G879"
139 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","-7.4","0",NA,"5.7","0","-23.8","0","",,NA,"7.5","0",NA,"23.0","2","",,NA,"787.3","0.0","1085836"
140 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","-2.6","0",NA,"5.5","0","-12.6","0","",,NA,"57.3","0",NA,"24.0","9","",,NA,"638.3","0.0","1086082"
141 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","-11.8","0",NA,"4.2","0","-33.5","0","",,NA,"12.3","0",NA,"19.0","4","",,NA,"924.5","0.0","1086558"
142 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","-8.4","0",NA,"6.4","0","-27.3","0","",,NA,"13.4","0",NA,"17.0","5","",,NA,"818.9","0.0","1088015"
143 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","-12.1","0",NA,"2.6","0","-33.9","0","",,NA,"4.2","0",NA,"34.0","2","",,NA,"934.0","0.0","1091174"
144 | "FORT ST JAMES","54.455","-124.286","BC","-6.8","17","1.0","3.0","17","-26.5","17","0.0","17",NA,"0.6","17",NA,"","0","","",NA,"346.7","0.0","1092970"
145 | "FORT ST JAMES AUTO","54.455","-124.286","BC","-8.9","0",NA,"3.9","0","-28.2","0","",,NA,"1.2","0",NA,"17.0","0","",,NA,"834.2","0.0","1092975"
146 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","-6.2","22",NA,"6.0","17","-27.0","16","22.8","17",NA,"22.8","17",NA,"","5","","",NA,"218.0","0.0","1095018"
147 | "PRINCE GEORGE","53.884","-122.678","BC","-9.8","7",NA,"4.0","7","-33.0","7","",,NA,"6.7","7",NA,"","2","",,NA,"667.2","0.0","1096439"
148 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","-10.0","0",NA,"4.2","0","-32.8","0","",,NA,"12.7","0",NA,"14.0","3","",,NA,"868.0","0.0","1096453"
149 | "PRINCE GEORGE STP","53.880","-122.768","BC","-18.1","26","-12.3","4.5","6","-28.0","26","21.0","5",NA,"23.4","5",NA,"","5","","",NA,"180.5","0.0","1096468"
150 | "QUESNEL","53.026","-122.510","BC","-7.7","4",NA,"4.8","4","-27.6","4","",,NA,"0.0","4",NA,"","0","",,NA,"692.6","0.0","1096629"
151 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","-8.6","0",NA,"4.9","0","-29.4","0","",,NA,"21.4","0",NA,"21.0","4","",,NA,"824.4","0.0","1096631"
152 | "SPOKIN LAKE 4E","52.184","-121.686","BC","-11.0","0","-3.2","7.0","0","-35.0","0","54.0","0","116.0","54.0","0","110.0","30.0","9","","",NA,"897.7","0.0","1097646"
153 | "WILLIAMS LAKE A","52.183","-122.054","BC","-9.3","1",NA,"4.7","1","-26.8","0","43.0","0",NA,"32.0","0",NA,"","7","",,NA,"817.9","0.0","1098941"
154 | "VANDERHOOF","54.033","-124.017","BC","-10.2","0","-2.0","4.5","0","-31.0","0","1.4","0","4.0","3.2","0","8.0","0.0","1","","",NA,"873.2","0.0","1098D90"
155 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","-7.9","0",NA,"4.5","0","-29.5","0","76.0","0",NA,"76.0","0",NA,"55.0","12","","",NA,"803.9","0.0","109E7R6"
156 | "ABBOTSFORD A","49.025","-122.360","BC","1.7","0",NA,"10.3","0","-6.1","0","7.8","0",NA,"199.6","0",NA,"2.0","11","",,NA,"506.6","0.0","1100031"
157 | "AGASSIZ RCS","49.243","-121.760","BC","2.5","0","-1.1","11.7","0","-6.3","0","",,NA,"189.1","7",NA,"39.0","16","",,NA,"480.2","0.0","1100119"
158 | "AGASSIZ CDA","49.243","-121.760","BC","4.8","12","1.6","11.0","11","-2.0","10","0.0","11",NA,"135.4","11",NA,"","10","","",NA,"250.7","0.0","1100120"
159 | "WHISTLER - NESTERS","50.129","-122.955","BC","-3.6","0",NA,"4.7","0","-13.0","0","",,NA,"57.6","0",NA,"55.0","9","",,NA,"669.4","0.0","1100875"
160 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","-3.3","0",NA,"6.2","0","-13.4","0","",,NA,"74.6","0",NA,"92.0","9","",,NA,"659.0","0.0","1100881"
161 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","2.0","30","-0.9","3.0","30","1.0","30","0.0","30",NA,"0.4","30",NA,"","0","","",NA,"16.0","0.0","1101158"
162 | "CALLAGHAN VALLEY","50.144","-123.111","BC","-2.2","0",NA,"7.5","0","-14.1","0","",,NA,"127.7","0",NA,"128.0","10","",,NA,"626.1","0.0","1101300"
163 | "CLOVERDALE EAST","49.109","-122.698","BC","2.2","0",NA,"9.0","0","-4.5","0","23.8","0",NA,"207.0","0",NA,"1.0","11","","",NA,"488.3","0.0","1101708"
164 | "DELTA BURNS BOG","49.126","-123.002","BC","1.9","0",NA,"8.8","0","-8.6","0","",,NA,"194.3","0",NA,"","10","",,NA,"498.8","0.0","1102415"
165 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","2.3","0","-2.7","9.5","0","-6.5","0","0.0","0","0.0","173.1","0","138.0","0.0","11","","",NA,"485.9","0.0","1102425"
166 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","1.7","0",NA,"10.0","0","-6.0","0","14.8","0",NA,"212.0","0",NA,"0.0","11","","",NA,"504.1","0.0","1102912"
167 | "MISSION WEST ABBEY","49.153","-122.271","BC","1.8","0","-0.9","11.0","0","-6.5","0","30.0","0","148.0","237.2","0","112.0","18.0","12","","",NA,"500.7","0.0","1105192"
168 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"243.9","0",NA,"","20","",,NA,"","","1105210"
169 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","0.6","1","1.6","14.5","1","-10.0","1","136.0","1",NA,"168.0","1",NA,"0.0","11","","",NA,"522.1","0.0","1105658"
170 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","4",NA,"197.0","4",NA,"0.0","10","","",NA,"","","1105669"
171 | "PITT MEADOWS CS","49.208","-122.690","BC","2.0","1",NA,"9.4","1","-6.0","0","",,NA,"244.1","1",NA,"1.0","11","",,NA,"481.0","0.0","1106178"
172 | "POINT ATKINSON","49.330","-123.265","BC","4.1","0",NA,"9.8","0","-1.2","0","",,NA,"148.8","0",NA,"","10","",,NA,"431.3","0.0","1106200"
173 | "RICHMOND DALLYN 2","49.179","-123.087","BC","",,NA,"",,"",,"2.2","24",NA,"311.4","24",NA,"0.0","4","","",NA,"","","1106764"
174 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","2.1","1","-1.2","9.0","1","-6.0","1","0.0","1",NA,"193.0","1",NA,"0.0","8","","",NA,"476.1","0.0","1106CL2"
175 | "RICHMOND NATURE PARK","49.171","-123.093","BC","2.5","0","-0.9","9.0","0","-9.0","0","4.4","0","40.0","178.9","0","107.0","2.0","9","","",NA,"480.3","0.0","1106PF7"
176 | "SANDHEADS CS","49.106","-123.303","BC","3.9","2",NA,"8.9","2","-1.1","0","",,NA,"",,NA,"","","",,NA,"408.5","0.0","1107010"
177 | "SUMAS CANAL","49.113","-122.110","BC","3.5","20",NA,"12.0","15","-5.0","14","8.0","15",NA,"174.2","15",NA,"","8","","",NA,"159.0","0.0","1107785"
178 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","2.7","0",NA,"9.5","0","-4.9","0","",,NA,"155.6","0",NA,"","10","",,NA,"473.1","0.0","1108380"
179 | "VANCOUVER INTL A","49.195","-123.184","BC","2.6","0",NA,"8.9","0","-5.8","0","1.2","0",NA,"170.6","0",NA,"","10","",,NA,"478.8","0.0","1108395"
180 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","4.0","0",NA,"9.3","0","-2.5","0","",,NA,"187.3","0",NA,"","10","",,NA,"434.7","0.0","1108446"
181 | "WEST VANCOUVER AUT","49.347","-123.193","BC","3.0","0",NA,"10.0","0","-4.4","0","",,NA,"",,NA,"","","",,NA,"465.1","0.0","1108824"
182 | "WHISTLER ROUNDHOUSE","50.068","-122.947","BC","-2.5","5",NA,"11.5","5","-16.5","5","92.0","5",NA,"92.0","5",NA,"193.0","11","","",NA,"533.2","0.0","1108906"
183 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","3.4","0",NA,"10.9","0","-3.0","0","",,NA,"0.0","27",NA,"","0","",,NA,"452.5","0.0","1108910"
184 | "HOPE A","49.368","-121.498","BC","0.8","4",NA,"9.2","4","-8.3","4","",,NA,"143.2","4",NA,"","10","",,NA,"465.4","0.0","1113542"
185 | "HOPE AIRPORT","49.370","-121.493","BC","0.9","0",NA,"9.8","0","-8.3","0","",,NA,"108.4","0",NA,"42.0","7","",,NA,"530.2","0.0","1113543"
186 | "HOPE SLIDE","49.267","-121.233","BC","-3.5","0","-1.8","3.0","0","-17.0","0","144.0","0","204.0","193.2","0","135.0","76.0","16","","",NA,"667.2","0.0","1113581"
187 | "LILLOOET","50.684","-121.934","BC","-4.0","0",NA,"7.1","0","-19.3","0","",,NA,"",,NA,"","","",,NA,"682.9","0.0","1114619"
188 | "LYTTON A","50.224","-121.582","BC","-3.8","8",NA,"4.8","8","-16.8","8","",,NA,"9.1","8",NA,"","3","",,NA,"500.9","0.0","1114738"
189 | "LYTTON RCS","50.224","-121.582","BC","-3.3","2",NA,"7.2","2","-17.2","1","",,NA,"32.4","3",NA,"18.0","8","",,NA,"618.2","0.0","1114746"
190 | "JELLICOE","49.673","-120.333","BC","-6.8","1",NA,"2.5","1","-25.0","1","81.0","1",NA,"81.0","1",NA,"59.0","14","","",NA,"744.7","0.0","1123721"
191 | "KELOWNA","49.957","-119.378","BC","-3.9","8",NA,"3.3","8","-19.9","8","",,NA,"16.8","8",NA,"","6","",,NA,"502.6","0.0","1123939"
192 | "KELOWNA UBCO","49.941","-119.400","BC","-3.3","0",NA,"4.3","0","-16.3","0","",,NA,"42.6","0",NA,"28.0","8","",,NA,"661.6","0.0","1123996"
193 | "MERRITT","50.113","-120.778","BC","-5.8","0",NA,"8.2","0","-25.8","0","",,NA,"1.0","29",NA,"","1","",,NA,"738.6","0.0","1125073"
194 | "MERRITT STP","50.114","-120.801","BC","-5.1","0","-1.5","7.5","0","-22.0","0","59.2","0","261.0","60.6","0","168.0","0.0","8","","",NA,"716.1","0.0","1125079"
195 | "OKANAGAN CENTRE","50.056","-119.445","BC","-1.7","0","-1.7","5.5","0","-12.5","0","67.4","0","275.0","79.4","0","196.0","29.0","10","","",NA,"610.8","0.0","1125700"
196 | "OLIVER STP","49.179","-119.545","BC","-0.7","13","0.4","5.5","13","-11.0","13","30.2","13",NA,"32.2","13",NA,"","4","","",NA,"336.7","0.0","1125766"
197 | "OSOYOOS CS","49.028","-119.441","BC","-2.0","0","-1.3","5.9","0","-12.8","0","",,NA,"28.9","0",NA,"13.0","5","",,NA,"620.9","0.0","1125852"
198 | "PEACHLAND","49.783","-119.717","BC","-1.4","0","-1.0","5.0","0","-13.0","0","65.0","0","207.0","83.8","0","183.0","35.0","11","","",NA,"602.9","0.0","1126070"
199 | "PENTICTON A","49.463","-119.602","BC","-2.6","0",NA,"5.0","0","-15.2","0","45.5","0",NA,"57.6","0",NA,"33.0","10","",,NA,"639.7","0.0","1126146"
200 | "PRINCETON A","49.468","-120.513","BC","-6.7","0","-1.1","2.0","0","-25.0","0","76.0","0","202.0","80.8","0","222.0","58.0","10","","",NA,"765.5","0.0","1126510"
201 | "VERNON AUTO","50.223","-119.194","BC","-4.4","0",NA,"4.6","0","-18.5","0","",,NA,"27.4","0",NA,"","8","",,NA,"694.9","0.0","1128582"
202 | "VERNON NORTH","50.344","-119.271","BC","-3.8","0","-1.7","5.5","0","-16.5","0","49.2","0","104.0","51.0","0","89.0","26.0","9","","",NA,"677.2","0.0","1128583"
203 | "VERNON SILVER STAR LODGE","50.359","-119.056","BC","-8.0","0",NA,"6.0","0","-23.5","0","115.0","0",NA,"115.0","0",NA,"114.0","13","","",NA,"805.1","0.0","1128584"
204 | "PRINCETON CS","49.465","-120.510","BC","-7.2","0",NA,"2.1","0","-25.9","0","",,NA,"79.0","0",NA,"54.0","10","",,NA,"782.6","0.0","112FN0M"
205 | "SUMMERLAND CS","49.563","-119.649","BC","-3.2","0","-2.3","4.5","0","-14.3","0","",,NA,"20.4","0",NA,"","5","",,NA,"658.2","0.0","112G8L1"
206 | "MIDWAY","49.004","-118.772","BC","-5.8","2","-1.5","4.5","2","-23.5","2","55.0","2",NA,"55.0","2",NA,"34.0","12","","",NA,"689.6","0.0","1135126"
207 | "BILLINGS","49.017","-118.228","BC","-2.7","7","0.8","3.5","7","-15.5","7","54.4","7",NA,"57.0","7",NA,"29.0","10","","",NA,"496.9","0.0","1140876"
208 | "CASTLEGAR A","49.296","-117.633","BC","-2.6","0","-0.5","4.5","0","-12.0","0","67.6","0","104.0","70.0","0","78.0","33.0","8","","",NA,"639.7","0.0","1141455"
209 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","-1.3","4","0.1","5.0","2","-9.5","2","61.0","2",NA,"73.4","2",NA,"12.0","13","","",NA,"521.2","0.0","1141457"
210 | "KASLO","49.913","-116.921","BC","-3.0","0","-0.8","5.0","0","-14.0","0","80.8","0","123.0","84.0","0","76.0","46.0","10","","",NA,"650.0","0.0","1143900"
211 | "NAKUSP CS","50.269","-117.817","BC","-2.9","0",NA,"5.6","0","-12.5","0","",,NA,"85.9","0",NA,"44.0","15","",,NA,"648.0","0.0","1145297"
212 | "NELSON NE","49.586","-117.206","BC","-2.1","0",NA,"7.0","0","-13.5","0","80.6","0",NA,"98.4","0",NA,"43.0","11","","",NA,"623.2","0.0","1145442"
213 | "NEW DENVER","49.996","-117.370","BC","-2.5","3","-0.6","5.0","3","-14.5","3","81.0","3",NA,"83.8","3",NA,"40.0","8","","",NA,"574.2","0.0","1145460"
214 | "NELSON CS","49.491","-117.305","BC","-2.1","0",NA,"4.8","0","-15.2","0","",,NA,"52.6","0",NA,"17.0","12","",,NA,"624.5","0.0","1145M29"
215 | "WARFIELD RCS","49.112","-117.739","BC","-3.7","0",NA,"4.4","0","-14.9","0","",,NA,"63.0","0",NA,"34.0","11","",,NA,"672.8","0.0","1148705"
216 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","-3.3","0",NA,"5.1","0","-12.7","0","",,NA,"42.4","0",NA,"22.0","10","",,NA,"659.1","0.0","114B1F0"
217 | "NELSON RIXEN CREEK","49.512","-117.399","BC","-4.6","4",NA,"5.5","4","-14.5","4","72.0","4",NA,"72.0","4",NA,"52.0","10","","",NA,"610.1","0.0","114EMDM"
218 | "CRANBROOK A","49.612","-115.782","BC","-10.0","0",NA,"5.3","0","-28.2","0","58.8","0",NA,"47.0","0",NA,"40.0","8","",,NA,"869.5","0.0","1152105"
219 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","-9.6","0",NA,"5.6","0","-24.7","0","",,NA,"46.0","0",NA,"37.0","8","",,NA,"855.5","0.0","1152106"
220 | "FERNIE","49.489","-115.073","BC","-7.6","9","-1.5","4.0","9","-33.0","9","51.0","9",NA,"55.0","9",NA,"52.0","9","","",NA,"562.3","0.0","1152850"
221 | "FT STEELE DANDY CRK","49.524","-115.461","BC","-8.3","9",NA,"4.5","5","-26.5","4","54.0","5",NA,"54.0","5",NA,"37.0","8","","",NA,"578.7","0.0","1153034"
222 | "KIMBERLEY PCC","49.632","-115.962","BC","-6.7","14","0.2","5.0","14","-21.0","14","58.6","14",NA,"58.6","14",NA,"","5","","",NA,"419.4","0.0","1154203"
223 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","-7.1","10","0.1","4.0","10","-21.5","10","6.0","10",NA,"6.0","10",NA,"29.0","3","","",NA,"527.7","0.0","1154410"
224 | "SPARWOOD","49.745","-114.883","BC","-10.4","0","-3.0","2.0","0","-33.0","0","56.8","0","105.0","38.0","0","71.0","30.0","8","","",NA,"879.0","0.0","1157630"
225 | "SPARWOOD CS","49.745","-114.884","BC","-10.6","0",NA,"2.5","0","-33.0","0","",,NA,"",,NA,"22.0","","",,NA,"887.2","0.0","1157631"
226 | "WASA","49.807","-115.631","BC","0.7","28","7.5","4.5","28","-9.5","27","4.2","28",NA,"4.2","28",NA,"","1","","",NA,"51.9","0.0","1158730"
227 | "ASHCROFT","50.708","-121.281","BC","-4.4","0",NA,"6.5","0","-19.3","0","",,NA,"9.8","0",NA,"","4","",,NA,"693.7","0.0","1160515"
228 | "BLUE RIVER A","52.129","-119.290","BC","-8.4","0","-1.3","1.0","0","-31.0","0","63.6","0","62.0","37.4","0","42.0","28.0","7","","",NA,"818.2","0.0","1160899"
229 | "BLUE RIVER CS","52.129","-119.290","BC","-8.9","0",NA,"1.5","0","-31.4","0","",,NA,"35.1","0",NA,"41.0","8","",,NA,"835.3","0.0","1160H99"
230 | "CLEARWATER AUTO","51.653","-120.082","BC","-6.4","0",NA,"2.2","0","-27.8","0","",,NA,"25.4","14",NA,"39.0","4","",,NA,"756.9","0.0","1161650"
231 | "CLINTON A","51.266","-121.685","BC","-11.7","9",NA,"4.1","9","-33.3","9","",,NA,"16.7","9",NA,"","5","",,NA,"653.6","0.0","1161662"
232 | "CLINTON RCS","51.144","-121.505","BC","-9.2","0",NA,"2.6","0","-26.3","0","",,NA,"45.7","0",NA,"35.0","9","",,NA,"844.5","0.0","1161663"
233 | "CRISS CREEK","51.030","-120.728","BC","-10.0","0","-2.8","2.0","0","-31.0","0","61.8","0","164.0","61.8","0","160.0","30.0","11","","",NA,"866.9","0.0","1162177"
234 | "KAMLOOPS A","50.703","-120.449","BC","-4.3","0",NA,"8.1","0","-19.5","0","32.2","0",NA,"29.4","0",NA,"19.0","8","",,NA,"690.3","0.0","1163781"
235 | "KAMLOOPS AUT","50.702","-120.442","BC","-4.0","0",NA,"7.9","0","-19.7","0","",,NA,"29.1","0",NA,"10.0","7","",,NA,"682.4","0.0","1163842"
236 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","-8.5","0",NA,"4.0","0","-32.0","0","69.4","0",NA,"69.4","0",NA,"45.0","11","","",NA,"820.8","0.0","1165793"
237 | "RED LAKE","50.935","-120.800","BC","-8.0","0","-1.9","2.5","0","-23.0","0","63.0","0","138.0","63.0","0","136.0","40.0","11","","",NA,"805.2","0.0","1166658"
238 | "SILVER CREEK","50.545","-119.350","BC","-4.1","0","-1.4","6.0","0","-20.0","0","60.4","0","114.0","63.6","0","93.0","40.0","11","","",NA,"685.9","0.0","1167337"
239 | "SUN PEAKS MOUNTAIN","50.903","-119.911","BC","-7.8","0",NA,"5.0","0","-20.0","0","65.0","0",NA,"65.0","0",NA,"93.0","13","","",NA,"800.6","0.0","1168204"
240 | "VAVENBY","51.576","-119.778","BC","-6.4","0","-1.7","2.5","0","-28.0","0","65.6","0","216.0","66.0","0","160.0","38.0","12","","",NA,"757.6","0.0","1168520"
241 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","-5.9","0",NA,"6.0","0","-21.0","0","56.8","0",NA,"56.8","0",NA,"30.0","9","","",NA,"739.5","0.0","116C8P0"
242 | "SALMON ARM CS","50.703","-119.291","BC","-3.5","0","-1.8","5.6","0","-19.3","0","",,NA,"43.8","0",NA,"24.0","9","",,NA,"665.4","0.0","116FRMN"
243 | "SUN PEAKS LOWER","50.887","-119.883","BC","-8.4","2",NA,"5.0","1","-22.0","1","76.2","1",NA,"76.2","1",NA,"56.0","15","","",NA,"765.6","0.0","116Q20D"
244 | "SUN PEAKS UPPER","50.902","-119.918","BC","-7.8","2",NA,"5.0","1","-18.0","1","75.0","1",NA,"75.0","1",NA,"117.0","13","","",NA,"748.2","0.0","116QK0M"
245 | "GOLDEN A","51.299","-116.982","BC","-8.7","0","-0.8","4.5","0","-22.0","0","42.4","0","100.0","30.8","0","70.0","28.0","9","","",NA,"827.3","0.0","1173210"
246 | "GOLDEN AIRPORT","51.300","-116.984","BC","-9.1","0",NA,"4.4","0","-21.7","0","",,NA,"33.8","0",NA,"26.0","9","",,NA,"838.7","0.0","1173220"
247 | "GOLDSTREAM RIVER","51.630","-118.425","BC","-4.0","0","2.5","4.0","0","-22.0","0","75.0","0","67.0","75.0","0","64.0","65.0","10","","",NA,"683.0","0.0","1173242"
248 | "MICA DAM","52.053","-118.585","BC","-6.6","6","-2.2","0.0","4","-17.0","5","69.4","4",NA,"69.4","4",NA,"68.0","10","","",NA,"615.8","0.0","1175122"
249 | "REVELSTOKE A","50.967","-118.183","BC","-4.5","10",NA,"3.8","10","-18.4","10","",,NA,"14.4","10",NA,"","4","",,NA,"472.6","0.0","1176745"
250 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","-4.1","0",NA,"4.1","0","-18.1","0","",,NA,"44.0","0",NA,"41.0","9","",,NA,"684.3","0.0","1176755"
251 | "YOHO PARK","51.443","-116.345","BC","-14.6","0",NA,"-1.8","0","-34.4","0","",,NA,"10.8","0",NA,"80.0","4","",,NA,"1010.2","0.0","11790J1"
252 | "CHETWYND A","55.687","-121.627","BC","-7.0","0","2.2","9.0","0","-38.5","0","6.8","0","28.0","2.6","0","14.0","14.0","1","","",NA,"773.7","0.0","1181508"
253 | "DAWSON CREEK A","55.742","-120.183","BC","-6.2","3",NA,"9.1","3","-37.7","3","",,NA,"0.0","16",NA,"","0","",,NA,"676.6","0.0","1182289"
254 | "FORT ST. JOHN A","56.238","-120.740","BC","-8.1","0",NA,"6.6","0","-36.6","0","3.4","0",NA,"5.0","0",NA,"12.0","3","",,NA,"808.0","0.0","1183001"
255 | "MACKENZIE","55.299","-123.133","BC","-10.4","6",NA,"2.6","6","-35.3","6","",,NA,"1.0","6",NA,"","1","",,NA,"710.5","0.0","1184791"
256 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","-10.6","0",NA,"2.3","0","-34.8","0","",,NA,"8.9","0",NA,"36.0","3","",,NA,"886.1","0.0","1184793"
257 | "DEASE LAKE A","58.422","-130.031","BC","-15.1","6",NA,"7.4","6","-39.4","6","",,NA,"1.0","6",NA,"","1","",,NA,"826.4","0.0","1192341"
258 | "FORT NELSON A","58.836","-122.597","BC","-14.7","0",NA,"5.3","0","-41.3","0","12.5","0",NA,"13.9","0",NA,"39.0","4","",,NA,"1015.1","0.0","1192946"
259 | "FORT NELSON","58.841","-122.574","BC","-14.4","0",NA,"4.8","0","-41.4","0","",,NA,"9.2","0",NA,"30.0","4","",,NA,"1005.4","0.0","1192948"
260 | "DEASE LAKE (AUT)","58.426","-130.025","BC","-14.4","0",NA,"7.8","0","-40.0","0","",,NA,"6.0","0",NA,"16.0","2","",,NA,"1002.9","0.0","119BLM0"
261 | "ATLIN","59.567","-133.700","BC","-6.8","0","1.3","7.5","0","-29.5","0","2.0","0","6.0","3.2","0","9.0","0.0","3","","",NA,"767.7","0.0","1200560"
262 | "PLEASANT CAMP","59.450","-136.367","BC","-6.3","0","0.0","6.0","0","-24.0","0","22.0","0","12.0","163.5","0","75.0","0.0","16","","",NA,"753.4","0.0","1206197"
263 |
--------------------------------------------------------------------------------
/data/eng-climate-summaries-British Columbia-8,2017.csv:
--------------------------------------------------------------------------------
1 | "Environment and Climate Change Canada"
2 | "Monthly Values for August - 2017"
3 |
4 | "Legend"
5 | "Stn_Name","Station Name"
6 | "Lat","Latitude (North + , degrees)"
7 | "Long","Longitude (West - , degrees)"
8 | "Prov","Province"
9 | "Tm","Mean Temperature (°C)"
10 | "DwTm","Days without Valid Mean Temperature"
11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)"
12 | "Tx","Highest Monthly Maximum Temperature (°C)"
13 | "DwTx","Days without Valid Maximum Temperature"
14 | "Tn","Lowest Monthly Minimum Temperature (°C)"
15 | "DwTn","Days without Valid Minimum Temperature"
16 | "S","Snowfall (cm)"
17 | "DwS","Days without Valid Snowfall"
18 | "S%N","Percent of Normal (1981-2010) Snowfall"
19 | "P","Total Precipitation (mm)"
20 | "DwP","Days without Valid Precipitation"
21 | "P%N","Percent of Normal (1981-2010) Precipitation"
22 | "S_G","Snow on the ground at the end of the month (cm)"
23 | "Pd","Number of days with Precipitation 1.0 mm or more"
24 | "BS","Bright Sunshine (hours)"
25 | "DwBS","Days without Valid Bright Sunshine"
26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine"
27 | "HDD","Degree Days below 18 °C"
28 | "CDD","Degree Days above 18 °C"
29 | "Clim_ID","Climate Identifier"
30 | "NA","Not Available"
31 |
32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID"
33 | "CHEMAINUS","48.935","-123.742","BC","20.9","0",NA,"31.5","0","11.5","0","0.0","0",NA,"2.7","0",NA,"0.0","1","","",NA,"2.1","91.8","1011500"
34 | "LAKE COWICHAN","48.829","-124.052","BC","20.7","13","2.7","36.0","9","8.0","9","0.0","10",NA,"5.0","10",NA,"0.0","2","","",NA,"1.5","50.8","1012055"
35 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"29.0","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475"
36 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","17.1","4",NA,"25.2","4","11.2","3","",,NA,"2.6","4",NA,"","2","",,NA,"28.8","4.9","1012710"
37 | "GALIANO NORTH","48.985","-123.573","BC","19.2","14",NA,"30.5","14","12.0","14","0.0","14",NA,"0.6","14",NA,"0.0","0","","",NA,"3.6","24.3","10130MN"
38 | "MALAHAT","48.575","-123.530","BC","20.9","0",NA,"32.5","0","10.3","0","",,NA,"4.2","0",NA,"","2","",,NA,"4.4","93.8","1014820"
39 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"0.0","17",NA,"0.0","17",NA,"0.0","0","","",NA,"","","1015105"
40 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"0.0","0",NA,"4.4","0","15.0","0.0","1","","",NA,"","","1015628"
41 | "NORTH COWICHAN","48.824","-123.719","BC","20.0","0",NA,"33.6","0","9.1","0","",,NA,"3.4","0",NA,"","2","",,NA,"4.0","66.4","1015630"
42 | "NORTH PENDER ISLAND","48.764","-123.287","BC","20.4","3",NA,"33.0","3","10.5","3","0.0","3",NA,"3.4","3",NA,"0.0","1","","",NA,"1.9","69.8","1015638"
43 | "RACE ROCKS","48.298","-123.531","BC","15.2","0",NA,"28.2","0","10.1","0","",,NA,"",,NA,"","","",,NA,"98.4","12.6","1016640"
44 | "SAANICHTON CDA","48.622","-123.419","BC","18.5","2","1.4","28.5","1","10.0","1","0.0","1",NA,"3.6","1",NA,"0.0","1","","",NA,"12.2","27.5","1016940"
45 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","20.7","0","2.4","30.0","0","13.0","0","0.0","0",NA,"2.4","0","9.0","0.0","1","","",NA,"1.0","85.1","1016995"
46 | "SATURNA CAPMON CS","48.775","-123.128","BC","19.3","0",NA,"28.3","0","10.2","0","",,NA,"5.0","0",NA,"","1","",,NA,"19.2","58.4","1017099"
47 | "SATURNA ISLAND CS","48.784","-123.045","BC","18.4","0",NA,"26.1","0","11.9","0","",,NA,"3.8","0",NA,"","1","",,NA,"16.8","30.4","1017101"
48 | "SHAWNIGAN LAKE","48.647","-123.626","BC","20.3","0","2.5","34.5","0","10.5","0","0.0","0",NA,"4.4","0","16.0","0.0","1","","",NA,"4.4","76.9","1017230"
49 | "SHERINGHAM POINT","48.377","-123.921","BC","14.4","0",NA,"30.4","0","9.0","0","",,NA,"6.4","0",NA,"","2","",,NA,"116.5","6.0","1017254"
50 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","18.5","0",NA,"29.7","0","9.0","0","",,NA,"1.1","0",NA,"","0","",,NA,"13.0","29.9","1018598"
51 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"0.0","0",NA,"0.0","0","0.0","0.0","0","","",NA,"","","1018605"
52 | "VICTORIA GONZALES CS","48.413","-123.325","BC","17.3","0",NA,"29.2","0","10.6","0","",,NA,"1.4","0",NA,"","1","",,NA,"42.9","21.7","1018611"
53 | "VICTORIA INTL A","48.647","-123.426","BC","18.2","0",NA,"29.6","0","9.8","0","0.0","0",NA,"3.4","0",NA,"","2","",,NA,"17.7","22.7","1018621"
54 | "WILLIAM HEAD","48.340","-123.539","BC","18.6","0","2.1","27.0","0","10.0","0","0.0","0",NA,"2.6","0","12.0","0.0","1","","",NA,"6.3","24.9","1018935"
55 | "BALLENAS ISLAND","49.350","-124.160","BC","19.4","0",NA,"25.4","0","14.2","0","",,NA,"3.2","0",NA,"","1","",,NA,"3.1","46.0","1020590"
56 | "CAMPBELL RIVER A","49.952","-125.273","BC","18.9","0","1.7","34.0","0","7.0","0","0.0","0",NA,"6.4","0","14.0","0.0","2","","",NA,"22.5","51.2","1021261"
57 | "CAPE MUDGE","49.998","-125.195","BC","19.2","0","2.0","30.5","0","11.5","0","0.0","0",NA,"6.0","0","13.0","0.0","2","","",NA,"6.1","41.9","1021330"
58 | "CHROME ISLAND","49.472","-124.683","BC","20.1","0",NA,"32.0","0","12.0","0","0.0","0",NA,"1.6","0",NA,"0.0","1","","",NA,"1.2","67.5","1021500"
59 | "COMOX A","49.717","-124.900","BC","19.8","0","1.9","30.1","0","11.5","0","0.0","0",NA,"6.4","0","22.0","","1","",,NA,"4.0","59.9","1021830"
60 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","20.2","0",NA,"31.5","0","8.5","0","0.0","0",NA,"10.0","0",NA,"0.0","2","","",NA,"3.9","73.3","1021960"
61 | "COURTENAY GRANTHAM","49.763","-124.999","BC","20.9","15",NA,"30.5","15","10.5","15","0.0","15",NA,"7.6","15",NA,"","1","","",NA,"0.0","47.1","1021988"
62 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","19.3","17",NA,"33.5","12","7.0","11","0.0","12",NA,"1.2","12",NA,"0.0","0","","",NA,"5.0","23.1","1021989"
63 | "ENTRANCE ISLAND","49.209","-123.811","BC","19.4","0",NA,"25.9","0","14.7","0","",,NA,"2.4","0",NA,"","1","",,NA,"3.4","48.2","1022689"
64 | "FANNY ISLAND","50.454","-125.993","BC","14.6","0",NA,"27.7","0","9.8","0","",,NA,"8.8","0",NA,"","2","",,NA,"107.2","1.6","1022795"
65 | "HERIOT BAY SE","50.099","-125.203","BC","19.3","3",NA,"31.0","3","10.0","3","0.0","3",NA,"5.2","3",NA,"0.0","2","","",NA,"5.1","41.2","1023462"
66 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","18.4","15","2.0","32.0","15","7.5","15","0.0","15",NA,"0.0","15",NA,"0.0","0","","",NA,"8.7","15.6","1024638"
67 | "NANAIMO A","49.054","-123.870","BC","20.0","0",NA,"34.0","0","9.5","0","0.0","0",NA,"3.0","0",NA,"0.0","1","","",NA,"6.3","67.6","1025369"
68 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"0.0","0",NA,"2.2","0","8.0","0.0","1","","",NA,"","","10253G0"
69 | "PINE ISLAND","50.976","-127.728","BC","13.9","3","0.6","19.0","3","10.0","3","0.0","3",NA,"47.4","3",NA,"0.0","13","","",NA,"113.7","0.0","1026170"
70 | "PORT HARDY A","50.681","-127.367","BC","14.8","0",NA,"27.0","0","7.1","0","0.0","0",NA,"35.0","0",NA,"","7","",,NA,"100.7","0.1","1026271"
71 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","19.2","0",NA,"30.5","0","9.3","0","",,NA,"3.5","0",NA,"","1","",,NA,"9.9","46.0","1026562"
72 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","19.2","4","2.4","31.0","4","10.0","4","0.0","4",NA,"4.8","4",NA,"","2","","",NA,"6.9","38.8","1026565"
73 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","19.2","0","1.8","31.5","0","9.0","0","0.0","0",NA,"8.8","0","18.0","0.0","4","","",NA,"8.6","45.6","1026639"
74 | "SISTERS ISLAND","49.487","-124.435","BC","19.8","0",NA,"28.3","0","14.8","0","",,NA,"",,NA,"","","",,NA,"2.4","58.0","1027403"
75 | "ENTRANCE ISLAND","49.209","-123.809","BC","19.4","2",NA,"26.0","2","15.0","2","0.0","2",NA,"4.0","2",NA,"0.0","1","","",NA,"3.4","42.7","102BFHH"
76 | "CAPE BEALE LIGHT","48.786","-125.216","BC","15.1","0","1.0","27.5","0","10.0","0","0.0","0",NA,"30.6","0","41.0","0.0","2","","",NA,"98.9","8.3","1031316"
77 | "ESTEVAN POINT","49.383","-126.543","BC","16.1","4","1.4","25.0","4","10.5","4","0.0","4",NA,"41.0","4",NA,"0.0","6","","",NA,"54.0","3.9","1032730"
78 | "ESTEVAN POINT CS","49.383","-126.543","BC","15.4","0",NA,"23.7","0","10.3","0","",,NA,"45.9","0",NA,"","6","",,NA,"81.9","2.0","1032731"
79 | "LENNARD ISLAND","49.111","-125.923","BC","14.5","0",NA,"26.0","0","9.5","0","0.0","0",NA,"42.8","0","51.0","0.0","6","","",NA,"110.3","2.8","1034600"
80 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","17.7","0","1.1","34.5","0","7.0","0","0.0","0",NA,"15.6","0","17.0","0.0","2","","",NA,"32.7","24.8","1035612"
81 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","16.7","0","0.4","27.5","0","11.0","0","0.0","0",NA,"45.6","0","46.0","0.0","7","","",NA,"60.2","18.7","1035614"
82 | "PACHENA POINT","48.723","-125.097","BC","15.0","0","0.8","28.0","0","9.0","0","0.0","0",NA,"39.0","0","46.0","0.0","6","","",NA,"101.5","8.8","1035940"
83 | "PORT ALBERNI COX LAKE","49.202","-124.752","BC","19.5","7","1.9","37.0","7","8.0","7","0.0","7",NA,"4.6","7",NA,"0.0","2","","",NA,"9.1","45.7","1036208"
84 | "QUATSINO","50.534","-127.653","BC","16.2","4","0.4","29.0","4","10.0","4","0.0","4",NA,"29.2","4",NA,"0.0","7","","",NA,"53.6","3.9","1036570"
85 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","20.0","3",NA,"35.9","3","6.0","3","",,NA,"0.6","3",NA,"","0","",,NA,"6.5","63.6","1036B06"
86 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","13.9","4",NA,"17.3","2","10.7","2","",,NA,"42.8","4",NA,"","9","",,NA,"109.6","0.0","1037090"
87 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","14.2","3",NA,"19.8","3","10.3","1","",,NA,"33.6","3",NA,"","7","",,NA,"106.2","0.0","1037553"
88 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","19.7","18",NA,"36.0","18","10.0","18","",,NA,"1.6","30",NA,"","1","","",NA,"11.9","33.6","1037899"
89 | "TOFINO A","49.082","-125.773","BC","16.0","0","1.0","31.5","0","8.5","0","0.0","0",NA,"40.6","0","46.0","0.0","6","","",NA,"75.4","12.5","1038205"
90 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","16.3","0","1.3","32.0","0","8.5","0","0.0","0",NA,"45.4","0","52.0","0.0","2","","",NA,"65.4","13.9","1038332"
91 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","18.5","0",NA,"33.0","0","3.5","0","0.0","0",NA,"43.9","0",NA,"0.0","9","","",NA,"24.1","40.4","1039035"
92 | "GIBSONS GOWER POINT","49.386","-123.541","BC","19.2","1","1.4","26.5","1","13.5","1","0.0","1",NA,"11.2","1",NA,"0.0","1","","",NA,"3.9","40.6","1043152"
93 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","19.7","0","1.5","28.0","0","15.0","0","0.0","0",NA,"5.6","0","16.0","0.0","1","","",NA,"0.0","53.9","1045100"
94 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","19.5","0",NA,"27.3","0","14.6","0","",,NA,"17.2","0",NA,"","1","",,NA,"1.7","47.4","10459NN"
95 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"0.0","0",NA,"5.0","0",NA,"0.0","1","","",NA,"","","1046115"
96 | "PORT MELLON","49.526","-123.496","BC","19.8","0",NA,"30.7","0","11.7","0","",,NA,"15.8","0",NA,"","1","",,NA,"4.0","60.6","1046332"
97 | "POWELL RIVER A","49.834","-124.500","BC","18.5","0","1.3","30.0","0","8.0","0","0.0","0",NA,"4.6","0","10.0","0.0","1","","",NA,"15.4","31.8","1046391"
98 | "POWELL RIVER","49.835","-124.497","BC","18.6","0",NA,"30.2","0","8.4","0","",,NA,"",,NA,"","","",,NA,"14.4","33.2","1046392"
99 | "SECHELT AUT","49.458","-123.715","BC","19.0","0",NA,"30.2","0","10.1","0","",,NA,"5.6","0",NA,"","2","",,NA,"11.9","41.5","1047172"
100 | "SQUAMISH AIRPORT","49.783","-123.161","BC","19.7","0",NA,"33.2","0","8.9","0","",,NA,"3.1","0",NA,"","1","",,NA,"5.1","59.3","10476F0"
101 | "WHISTLER","50.129","-122.955","BC","19.2","0","2.8","35.0","0","5.5","0","0.0","0",NA,"3.2","0","7.0","0.0","1","","",NA,"20.3","59.0","1048898"
102 | "CAPE ST JAMES","51.936","-131.016","BC","13.8","2",NA,"21.0","1","10.9","1","",,NA,"113.8","2",NA,"","23","",,NA,"122.1","0.0","1051351"
103 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","13.7","2",NA,"16.6","1","11.1","1","",,NA,"199.6","2",NA,"","17","",,NA,"123.4","0.0","1054222"
104 | "LANGARA","54.255","-133.058","BC","13.6","1","0.0","19.0","1","10.5","1","0.0","1",NA,"170.0","1",NA,"0.0","16","",,NA,"131.6","0.0","1054500"
105 | "LANGARA ISLAND RCS","54.255","-133.058","BC","13.4","9",NA,"17.0","9","10.9","8","",,NA,"146.9","9",NA,"","11","",,NA,"101.4","0.0","1054503"
106 | "ROSE SPIT (AUT)","54.159","-131.661","BC","14.2","0",NA,"18.7","0","8.0","0","",,NA,"178.8","0",NA,"","17","",,NA,"117.2","0.0","1056869"
107 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","15.7","0",NA,"23.6","0","9.6","0","",,NA,"50.1","0",NA,"","13","",,NA,"74.6","3.5","1057051"
108 | "SANDSPIT","53.254","-131.814","BC","16.1","7",NA,"22.7","7","9.5","7","",,NA,"33.8","7",NA,"","10","",,NA,"49.3","2.7","1057052"
109 | "ADDENBROKE ISLAND","51.604","-127.864","BC","15.8","1","0.6","29.0","1","10.5","1","0.0","1",NA,"181.2","1",NA,"0.0","15","","",NA,"69.8","3.8","1060080"
110 | "BELLA BELLA","52.185","-128.157","BC","15.7","5",NA,"32.9","5","6.8","5","",,NA,"168.0","5",NA,"","13","",,NA,"64.7","5.6","1060815"
111 | "BELLA COOLA A","52.388","-126.596","BC","17.6","0","0.7","35.0","0","1.0","0","0.0","0",NA,"52.1","0","86.0","0.0","11","","",NA,"41.9","30.5","1060841"
112 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","17.3","0",NA,"35.1","0","8.6","0","",,NA,"41.9","0",NA,"","9","",,NA,"42.9","20.7","1060844"
113 | "BOAT BLUFF","52.643","-128.524","BC","16.0","0","0.9","33.5","0","10.5","0","0.0","0",NA,"302.4","0","131.0","0.0","18","","",NA,"81.8","18.4","1060901"
114 | "BONILLA ISLAND","53.493","-130.638","BC","14.0","1","0.0","19.5","1","11.0","1","0.0","1",NA,"193.4","1",NA,"0.0","18","","",NA,"120.8","0.0","1060902"
115 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","13.2","5",NA,"16.8","5","11.0","1","",,NA,"95.4","5",NA,"","12","",,NA,"123.6","0.0","1060R0K"
116 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","16.6","3",NA,"32.1","2","10.5","1","",,NA,"158.2","3",NA,"","15","",,NA,"57.6","18.2","1061458"
117 | "CUMSHEWA ISLAND","53.030","-131.602","BC","15.4","2",NA,"22.0","1","11.2","1","",,NA,"12.4","2",NA,"","5","",,NA,"77.2","2.8","1062251"
118 | "DRYAD POINT","52.185","-128.112","BC","16.4","0","0.6","31.0","0","10.5","0","0.0","0",NA,"188.6","0","130.0","0.0","16","","",NA,"62.1","13.3","1062544"
119 | "GREEN ISLAND","54.569","-130.708","BC","14.4","0","-0.4","23.5","0","11.0","0","0.0","0",NA,"219.5","0","132.0","0.0","18","","",NA,"113.0","0.3","1063298"
120 | "GREY ISLET (AUT)","54.580","-130.698","BC","14.4","2",NA,"22.5","1","11.7","1","",,NA,"174.2","2",NA,"","17","",,NA,"103.4","0.2","1063303"
121 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","13.6","0",NA,"18.7","0","9.4","0","",,NA,"28.2","0",NA,"","9","",,NA,"136.5","0.0","1063461"
122 | "HOLLAND ROCK","54.172","-130.361","BC","13.7","0",NA,"21.2","0","11.2","0","",,NA,"161.4","0",NA,"","13","",,NA,"132.0","0.0","1063496"
123 | "IVORY ISLAND","52.270","-128.407","BC","15.5","0","0.7","27.0","0","11.5","0","0.0","0",NA,"200.4","0","122.0","0.0","15","","",NA,"80.0","3.8","1063690"
124 | "KEMANO","53.563","-127.943","BC","17.5","1","1.0","35.0","1","10.0","0","0.0","1",NA,"112.2","1",NA,"0.0","19","","",NA,"61.7","45.5","1064020"
125 | "KITIMAT TOWNSITE","54.054","-128.634","BC","16.9","0","0.4","35.0","0","6.0","0","0.0","0",NA,"143.6","0","150.0","0.0","16","","",NA,"80.1","46.0","1064320"
126 | "KITIMAT 2","54.010","-128.705","BC","17.4","6","0.3","35.0","6","5.0","6","0.0","6",NA,"145.9","6",NA,"0.0","14","","",NA,"60.0","44.8","1064321"
127 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","13.7","0",NA,"19.6","0","11.1","0","",,NA,"",,NA,"","","",,NA,"132.8","0.0","1064728"
128 | "MCINNES ISLAND","52.262","-128.719","BC","14.8","0","0.1","19.5","0","11.5","0","0.0","0",NA,"153.0","0","115.0","0.0","14","",,NA,"100.3","0.0","1065010"
129 | "PRINCE RUPERT","54.286","-130.445","BC","14.2","8",NA,"24.4","8","9.9","7","",,NA,"246.5","8",NA,"","15","",,NA,"88.3","0.1","1066482"
130 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"0.0","14",NA,"212.4","14",NA,"0.0","9","","",NA,"","","1066488"
131 | "TERRACE PCC","54.502","-128.625","BC","18.0","1","1.3","34.5","1","9.0","1","0.0","1",NA,"61.0","1",NA,"0.0","13","","",NA,"49.6","50.5","1068131"
132 | "TERRACE A","54.469","-128.578","BC","17.3","2",NA,"33.7","0","8.3","2","0.0","0",NA,"79.2","0",NA,"","11","",,NA,"64.9","45.7","1068134"
133 | "TRIPLE ISLAND","54.295","-130.880","BC","14.0","0",NA,"19.5","0","11.5","0","0.0","0",NA,"144.6","0",NA,"0.0","17","","",NA,"123.2","0.0","1068250"
134 | "EQUITY SILVER","54.199","-126.277","BC","13.2","0","1.6","27.5","0","3.5","0","0.0","0",NA,"25.8","0","48.0","0.0","5","","",NA,"155.2","5.3","1072692"
135 | "HOUSTON","54.396","-126.668","BC","16.1","8",NA,"31.5","8","3.0","8","0.0","13",NA,"1.0","13",NA,"0.0","1","","",NA,"51.4","7.8","1073615"
136 | "SMITHERS","54.825","-127.183","BC","17.0","9",NA,"31.6","9","4.2","9","",,NA,"11.1","9",NA,"","2","",,NA,"41.7","19.8","1077499"
137 | "SMITHERS A","54.825","-127.183","BC","16.6","0","2.0","33.0","0","5.0","0","0.0","0",NA,"16.8","0","38.0","0.0","5","","",NA,"71.6","27.5","1077500"
138 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","16.3","0",NA,"31.7","0","4.8","0","",,NA,"27.6","0",NA,"","5","",,NA,"76.4","24.5","1077501"
139 | "SUSKWA VALLEY","55.289","-127.171","BC","13.7","2","-0.3","30.5","2","2.5","2","0.0","2",NA,"55.2","2",NA,"0.0","13","","",NA,"130.8","4.9","107G879"
140 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","15.4","0",NA,"28.8","0","6.4","0","",,NA,"9.2","0",NA,"","2","",,NA,"90.0","8.1","1085836"
141 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","20.8","0",NA,"36.8","0","7.7","0","",,NA,"1.2","0",NA,"","1","",,NA,"1.9","89.6","1086082"
142 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","15.7","0",NA,"33.8","0","-1.3","0","",,NA,"7.6","0",NA,"","1","",,NA,"78.0","7.2","1086558"
143 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","15.9","0",NA,"32.9","0","-1.2","0","",,NA,"2.3","0",NA,"","1","",,NA,"72.0","5.6","1088015"
144 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","13.9","0",NA,"31.7","0","-0.9","0","",,NA,"10.7","0",NA,"","4","",,NA,"127.9","1.8","1091174"
145 | "FORT ST JAMES","54.455","-124.286","BC","16.0","12","1.2","30.5","12","7.0","12","0.0","12",NA,"2.0","12",NA,"0.0","1","","",NA,"44.8","6.7","1092970"
146 | "FORT ST JAMES AUTO","54.455","-124.286","BC","16.3","0",NA,"31.1","0","6.1","0","",,NA,"16.9","0",NA,"","3","",,NA,"68.4","16.1","1092975"
147 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","16.1","10",NA,"30.5","7","2.5","7","0.0","7",NA,"9.4","7",NA,"0.0","3","","",NA,"52.1","11.2","1095018"
148 | "PRINCE GEORGE","53.884","-122.678","BC","15.9","11",NA,"33.5","11","3.0","11","",,NA,"19.0","11",NA,"","4","",,NA,"48.9","7.2","1096439"
149 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","15.9","3",NA,"33.7","3","3.0","1","",,NA,"18.7","3",NA,"","5","",,NA,"68.9","8.7","1096453"
150 | "PRINCE GEORGE STP","53.880","-122.768","BC","18.1","1","2.2","35.0","1","5.5","1","0.0","1",NA,"37.0","1",NA,"0.0","6","","",NA,"33.9","37.6","1096468"
151 | "QUESNEL","53.026","-122.510","BC","16.7","9",NA,"33.7","9","3.0","8","",,NA,"13.8","9",NA,"","3","",,NA,"40.9","12.1","1096629"
152 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","17.4","0",NA,"34.9","0","3.0","0","",,NA,"16.1","0",NA,"","6","",,NA,"45.2","27.5","1096631"
153 | "SPOKIN LAKE 4E","52.184","-121.686","BC","13.8","0","1.0","33.0","0","-4.0","0","0.0","0",NA,"25.8","0","49.0","0.0","7","","",NA,"131.2","0.3","1097646"
154 | "WILLIAMS LAKE A","52.183","-122.054","BC","17.6","1",NA,"31.9","1","2.7","0","0.0","12",NA,"11.8","18",NA,"","3","",,NA,"47.1","35.2","1098941"
155 | "VANDERHOOF","54.033","-124.017","BC","17.1","0","1.3","33.5","0","5.5","0","0.0","0",NA,"17.6","0","41.0","0.0","5","","",NA,"49.5","22.8","1098D90"
156 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","18.1","1",NA,"35.0","1","3.5","1","0.0","1",NA,"11.0","1",NA,"0.0","3","","",NA,"37.5","39.1","109E7R6"
157 | "ABBOTSFORD A","49.025","-122.360","BC","20.0","2",NA,"34.1","2","9.4","0","0.0","0",NA,"3.2","1",NA,"","1","",,NA,"2.7","60.1","1100031"
158 | "AGASSIZ RCS","49.243","-121.760","BC","20.1","3","1.3","33.3","3","8.5","1","",,NA,"7.7","4",NA,"","1","",,NA,"4.5","62.4","1100119"
159 | "AGASSIZ CDA","49.243","-121.760","BC","20.0","4","1.3","35.5","2","9.0","2","0.0","2",NA,"9.2","2",NA,"0.0","1","","",NA,"5.7","60.0","1100120"
160 | "WHISTLER - NESTERS","50.129","-122.955","BC","19.1","0",NA,"34.6","0","5.8","0","",,NA,"2.1","0",NA,"","1","",,NA,"26.0","59.8","1100875"
161 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","19.2","0",NA,"32.2","0","7.1","0","",,NA,"1.7","0",NA,"","1","",,NA,"41.6","80.3","1100881"
162 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","20.6","1","3.4","30.0","1","11.0","1","0.0","1",NA,"12.4","1",NA,"0.0","2","","",NA,"7.8","84.7","1101158"
163 | "CALLAGHAN VALLEY","50.144","-123.111","BC","18.4","0",NA,"32.5","0","5.5","0","",,NA,"4.5","0",NA,"","2","",,NA,"47.2","61.1","1101300"
164 | "CLOVERDALE EAST","49.109","-122.698","BC","20.7","3",NA,"32.5","3","11.5","3","0.0","3",NA,"5.4","3",NA,"0.0","1","","",NA,"0.9","75.8","1101708"
165 | "DELTA BURNS BOG","49.126","-123.002","BC","18.4","0",NA,"30.1","0","7.3","0","",,NA,"6.9","0",NA,"","1","",,NA,"14.8","26.7","1102415"
166 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","17.7","1","-0.2","27.5","1","9.5","1","0.0","1",NA,"5.2","1",NA,"0.0","1","","",NA,"22.8","15.1","1102425"
167 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","20.3","0",NA,"33.0","0","9.5","0","0.0","0",NA,"6.0","0",NA,"0.0","2","","",NA,"3.8","74.8","1102912"
168 | "HANEY UBC RF ADMIN","49.264","-122.573","BC","20.6","0","2.8","33.0","0","10.0","0","0.0","0",NA,"8.5","0","12.0","0.0","1","","",NA,"4.2","85.2","1103332"
169 | "MISSION WEST ABBEY","49.153","-122.271","BC","21.1","0","2.8","32.5","0","11.5","0","0.0","0",NA,"8.6","0","14.0","0.0","1","","",NA,"3.4","100.1","1105192"
170 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"6.9","0",NA,"","1","",,NA,"","","1105210"
171 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","17.7","8","3.7","31.0","8","0.0","8","0.0","8",NA,"30.0","8",NA,"","2","","",NA,"50.8","44.6","1105658"
172 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","10",NA,"12.0","10",NA,"","2","","",NA,"","","1105669"
173 | "PITT MEADOWS CS","49.208","-122.690","BC","20.7","0",NA,"33.0","0","10.4","0","",,NA,"6.5","0",NA,"","1","",,NA,"0.4","84.9","1106178"
174 | "POINT ATKINSON","49.330","-123.265","BC","19.0","5",NA,"27.4","5","14.2","3","",,NA,"16.6","5",NA,"","4","",,NA,"5.4","31.2","1106200"
175 | "RICHMOND DALLYN 2","49.179","-123.087","BC","",,NA,"",,"",,"0.0","0",NA,"7.4","0",NA,"0.0","1","","",NA,"","","1106764"
176 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","20.4","0","2.3","31.0","0","12.0","0","0.0","0",NA,"10.0","0","15.0","0.0","1","","",NA,"2.0","75.6","1106CL2"
177 | "RICHMOND NATURE PARK","49.171","-123.093","BC","19.9","2","1.7","31.5","2","9.5","2","0.0","2",NA,"7.6","2",NA,"0.0","1","","",NA,"0.7","56.4","1106PF7"
178 | "SANDHEADS CS","49.106","-123.303","BC","18.9","0",NA,"24.5","0","14.0","0","",,NA,"",,NA,"","","",,NA,"7.1","33.5","1107010"
179 | "SUMAS CANAL","49.113","-122.110","BC","23.9","26",NA,"38.0","21","4.5","20","0.0","21",NA,"1.0","21",NA,"0.0","1","","",NA,"0.0","29.6","1107785"
180 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","19.3","0",NA,"29.7","0","11.6","0","",,NA,"7.3","0",NA,"","1","",,NA,"2.5","41.4","1108380"
181 | "VANCOUVER INTL A","49.195","-123.184","BC","18.8","0",NA,"29.5","0","10.9","0","0.0","0",NA,"5.0","0",NA,"","1","",,NA,"6.7","32.5","1108395"
182 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","19.9","1",NA,"30.5","1","13.6","0","",,NA,"10.1","1",NA,"","1","",,NA,"0.1","57.6","1108446"
183 | "WEST VANCOUVER AUT","49.347","-123.193","BC","20.7","0",NA,"31.8","0","12.6","0","",,NA,"14.6","0",NA,"","1","",,NA,"2.4","85.2","1108824"
184 | "WHISTLER ROUNDHOUSE","50.068","-122.947","BC","14.3","3",NA,"25.0","3","3.5","3","0.0","3",NA,"0.5","3",NA,"0.0","0","","",NA,"113.4","11.1","1108906"
185 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","18.5","0",NA,"29.5","0","10.6","0","",,NA,"5.0","0",NA,"","1","",,NA,"9.4","26.1","1108910"
186 | "N VAN SEYMOUR HATCHERY","49.438","-122.967","BC","19.4","3","2.1","32.0","2","9.0","3","0.0","2",NA,"15.8","2",NA,"0.0","1","","",NA,"14.5","53.5","110N666"
187 | "HOPE A","49.368","-121.498","BC","21.7","2",NA,"37.2","1","9.4","1","",,NA,"3.6","2",NA,"","2","",,NA,"1.6","107.6","1113542"
188 | "HOPE AIRPORT","49.370","-121.493","BC","21.5","0",NA,"37.4","0","9.5","0","",,NA,"2.9","0",NA,"","1","",,NA,"2.0","111.2","1113543"
189 | "HOPE SLIDE","49.267","-121.233","BC","17.9","0","2.7","33.0","0","5.0","0","0.0","0",NA,"3.6","0","9.0","0.0","1","","",NA,"41.5","39.3","1113581"
190 | "LILLOOET","50.684","-121.934","BC","24.2","0",NA,"38.9","0","10.2","0","",,NA,"",,NA,"","","",,NA,"0.0","192.8","1114619"
191 | "LYTTON A","50.224","-121.582","BC","24.2","0",NA,"39.3","0","12.1","0","",,NA,"0.0","0",NA,"","0","",,NA,"0.0","190.7","1114738"
192 | "LYTTON RCS","50.224","-121.582","BC","24.3","0",NA,"40.1","0","12.1","0","",,NA,"0.2","0",NA,"","0","",,NA,"0.0","196.2","1114746"
193 | "HEDLEY N","49.364","-120.069","BC","24.0","12",NA,"41.0","12","9.0","12","0.0","12",NA,"0.6","12",NA,"","0","","",NA,"0.0","114.9","1123370"
194 | "JELLICOE","49.673","-120.333","BC","18.9","3",NA,"36.0","3","2.5","3","0.0","3",NA,"2.4","3",NA,"0.0","1","","",NA,"24.5","48.9","1123721"
195 | "KELOWNA","49.957","-119.378","BC","20.2","3",NA,"34.0","3","4.4","3","",,NA,"0.0","3",NA,"","0","",,NA,"7.1","69.1","1123939"
196 | "KELOWNA UBCO","49.941","-119.400","BC","22.2","0",NA,"35.8","0","7.7","0","",,NA,"0.2","0",NA,"","0","",,NA,"2.6","132.8","1123996"
197 | "MERRITT","50.113","-120.778","BC","19.5","0",NA,"37.8","0","3.3","0","",,NA,"2.2","0",NA,"","1","",,NA,"12.6","57.9","1125073"
198 | "MERRITT STP","50.114","-120.801","BC","20.7","0","2.2","38.0","0","6.0","0","0.0","0",NA,"2.0","0","10.0","0.0","1","","",NA,"5.9","91.0","1125079"
199 | "OKANAGAN CENTRE","50.056","-119.445","BC","22.7","0","2.3","33.0","0","11.0","0","0.0","0",NA,"1.0","0","3.0","0.0","1","","",NA,"1.7","147.8","1125700"
200 | "OLIVER STP","49.179","-119.545","BC","23.8","11","2.1","37.0","11","12.0","11","0.0","11",NA,"0.0","11",NA,"0.0","0","","",NA,"0.0","116.2","1125766"
201 | "OSOYOOS CS","49.028","-119.441","BC","23.1","0","0.8","36.9","0","8.4","0","",,NA,"0.6","0",NA,"","0","",,NA,"0.0","158.8","1125852"
202 | "PEACHLAND","49.783","-119.717","BC","22.6","0","1.7","33.0","0","10.0","0","0.0","0",NA,"0.6","0","2.0","0.0","0","","",NA,"2.7","144.9","1126070"
203 | "PENTICTON A","49.463","-119.602","BC","21.4","1",NA,"34.1","1","7.2","0","0.0","1",NA,"0.0","1",NA,"","0","",,NA,"2.6","105.9","1126146"
204 | "PRINCETON A","49.468","-120.513","BC","19.7","2","1.8","37.0","2","2.5","2","0.0","2",NA,"1.2","2",NA,"0.0","1","","",NA,"15.0","64.0","1126510"
205 | "VERNON AUTO","50.223","-119.194","BC","21.4","0",NA,"34.1","0","5.7","0","",,NA,"1.0","0",NA,"","0","",,NA,"5.3","110.8","1128582"
206 | "VERNON NORTH","50.344","-119.271","BC","22.7","0","2.3","35.0","0","7.0","0","0.0","0",NA,"1.0","0","3.0","0.0","0","","",NA,"3.9","149.7","1128583"
207 | "VERNON SILVER STAR LODGE","50.359","-119.056","BC","17.4","0",NA,"29.5","0","4.0","0","0.0","0",NA,"7.8","0",NA,"0.0","2","","",NA,"62.5","43.5","1128584"
208 | "PRINCETON CS","49.465","-120.510","BC","20.1","0",NA,"37.7","0","3.7","0","",,NA,"1.0","0",NA,"","0","",,NA,"12.7","78.1","112FN0M"
209 | "SUMMERLAND CS","49.563","-119.649","BC","22.6","0","1.6","34.9","0","8.8","0","",,NA,"0.0","0",NA,"","0","",,NA,"2.5","145.8","112G8L1"
210 | "MIDWAY","49.004","-118.772","BC","20.3","0","1.6","37.5","0","2.5","0","0.0","0",NA,"2.2","0","8.0","0.0","1","","",NA,"7.3","79.1","1135126"
211 | "BILLINGS","49.017","-118.228","BC","22.6","4","2.2","37.0","4","8.5","4","0.0","4",NA,"3.8","4",NA,"","1","","",NA,"0.0","123.8","1140876"
212 | "CASTLEGAR A","49.296","-117.633","BC","22.1","0","2.1","37.0","0","6.5","0","0.0","0",NA,"8.2","0","27.0","0.0","2","","",NA,"0.7","127.0","1141455"
213 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","22.1","0","2.2","36.0","0","10.5","0","0.0","0",NA,"14.6","0","43.0","0.0","1","","",NA,"1.0","127.5","1141457"
214 | "DUNCAN LAKE DAM","50.239","-116.972","BC","18.4","0","1.4","32.5","0","5.0","0","0.0","0",NA,"25.5","0","49.0","0.0","2","","",NA,"21.5","35.4","1142574"
215 | "KASLO","49.913","-116.921","BC","20.4","0","2.1","32.0","0","9.0","0","0.0","0",NA,"17.8","0","40.0","0.0","2","","",NA,"3.9","77.4","1143900"
216 | "NAKUSP CS","50.269","-117.817","BC","20.1","0",NA,"34.2","0","5.4","0","",,NA,"10.7","0",NA,"","1","",,NA,"15.8","80.5","1145297"
217 | "NELSON NE","49.586","-117.206","BC","21.0","0",NA,"34.5","0","8.0","0","0.0","0",NA,"23.2","0",NA,"0.0","2","","",NA,"2.2","95.8","1145442"
218 | "NEW DENVER","49.996","-117.370","BC","21.2","0","2.3","35.0","0","8.0","0","0.0","0",NA,"29.4","0","54.0","0.0","2","","",NA,"8.1","107.4","1145460"
219 | "NELSON CS","49.491","-117.305","BC","22.2","0",NA,"36.2","0","8.7","0","",,NA,"19.0","0",NA,"","1","",,NA,"0.0","130.5","1145M29"
220 | "WARFIELD RCS","49.112","-117.739","BC","23.0","1",NA,"38.4","1","8.0","0","",,NA,"3.9","1",NA,"","1","",,NA,"0.0","150.0","1148705"
221 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","23.1","1",NA,"35.2","1","10.7","0","",,NA,"8.4","1",NA,"","1","",,NA,"0.0","153.5","114B1F0"
222 | "NELSON RIXEN CREEK","49.512","-117.399","BC","21.4","4",NA,"35.5","4","7.5","4","0.0","4",NA,"34.3","4",NA,"0.0","2","","",NA,"5.7","98.2","114EMDM"
223 | "CRANBROOK A","49.612","-115.782","BC","20.6","2",NA,"33.9","0","3.5","2","0.0","0",NA,"2.8","0",NA,"","1","",,NA,"10.9","86.3","1152105"
224 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","20.7","0",NA,"33.8","0","4.0","0","",,NA,"1.0","0",NA,"","1","",,NA,"12.1","96.4","1152106"
225 | "FERNIE","49.489","-115.073","BC","18.8","6","2.5","34.0","6","2.5","6","0.0","6",NA,"21.8","6",NA,"0.0","6","","",NA,"13.9","33.3","1152850"
226 | "FT STEELE DANDY CRK","49.524","-115.461","BC","18.7","15",NA,"33.0","11","4.0","10","0.0","11",NA,"19.6","11",NA,"","4","","",NA,"10.9","22.1","1153034"
227 | "KIMBERLEY PCC","49.632","-115.962","BC","20.3","12","2.7","34.0","12","4.0","12","0.0","12",NA,"0.0","12",NA,"0.0","0","","",NA,"7.7","51.6","1154203"
228 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","20.1","8","2.4","34.0","8","5.0","8","0.0","8",NA,"0.0","8",NA,"0.0","0","","",NA,"13.8","62.8","1154410"
229 | "SPARWOOD","49.745","-114.883","BC","17.4","0","1.9","32.5","0","1.5","0","0.0","0","0.0","7.6","0","22.0","0.0","2","","",NA,"35.7","16.5","1157630"
230 | "SPARWOOD CS","49.745","-114.884","BC","17.3","0",NA,"32.5","0","1.5","0","",,NA,"7.0","0",NA,"","2","",,NA,"37.4","16.1","1157631"
231 | "WASA","49.807","-115.631","BC","20.3","6","2.6","32.5","3","5.5","3","0.0","3",NA,"26.0","3",NA,"0.0","2","","",NA,"10.1","68.4","1158730"
232 | "ASHCROFT","50.708","-121.281","BC","23.8","0",NA,"39.5","0","9.1","0","",,NA,"3.8","0",NA,"","2","",,NA,"0.3","180.1","1160515"
233 | "BLUE RIVER A","52.129","-119.290","BC","17.3","0","1.4","35.5","0","2.0","0","0.0","0",NA,"26.2","0","32.0","0.0","4","","",NA,"50.5","29.7","1160899"
234 | "BLUE RIVER CS","52.129","-119.290","BC","17.4","2",NA,"35.1","2","1.7","0","",,NA,"19.4","2",NA,"","4","",,NA,"45.4","28.5","1160H99"
235 | "CLEARWATER AUTO","51.653","-120.082","BC","19.8","0",NA,"35.7","0","4.9","0","",,NA,"21.1","0",NA,"","3","",,NA,"21.5","78.3","1161650"
236 | "CLINTON A","51.266","-121.685","BC","14.8","12",NA,"30.9","12","-1.5","11","",,NA,"10.5","12",NA,"","2","",,NA,"63.1","2.7","1161662"
237 | "CLINTON RCS","51.144","-121.505","BC","18.2","0",NA,"34.2","0","1.3","0","",,NA,"9.0","0",NA,"","2","",,NA,"38.0","44.1","1161663"
238 | "CRISS CREEK","51.030","-120.728","BC","14.9","5","1.7","32.0","5","-1.5","5","0.0","5",NA,"6.2","5",NA,"0.0","1","","",NA,"82.7","2.1","1162177"
239 | "DARFIELD","51.292","-120.183","BC","21.7","27","3.3","35.0","26","10.5","27","0.0","26",NA,"0.0","26",NA,"0.0","0","","",NA,"0.0","14.6","1162265"
240 | "KAMLOOPS A","50.703","-120.449","BC","22.1","0",NA,"38.5","0","6.9","0","0.0","0",NA,"1.8","0",NA,"","1","",,NA,"2.0","129.3","1163781"
241 | "KAMLOOPS AUT","50.702","-120.442","BC","22.0","1",NA,"38.1","1","7.0","0","",,NA,"0.8","1",NA,"","0","",,NA,"2.0","121.9","1163842"
242 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","18.3","0",NA,"34.0","0","6.0","0","0.0","0",NA,"18.8","0",NA,"0.0","4","","",NA,"33.4","42.8","1165793"
243 | "RED LAKE","50.935","-120.800","BC","18.4","6","3.5","33.0","6","3.0","6","0.0","2",NA,"5.0","2",NA,"0.0","2","","",NA,"21.6","31.2","1166658"
244 | "SILVER CREEK","50.545","-119.350","BC","19.4","0","1.0","34.5","0","4.0","0","0.0","0",NA,"1.9","0","6.0","0.0","1","","",NA,"16.1","59.8","1167337"
245 | "VAVENBY","51.576","-119.778","BC","18.6","0","1.1","36.5","0","4.5","0","0.0","0",NA,"14.2","0","33.0","0.0","2","","",NA,"31.5","51.6","1168520"
246 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","20.5","12",NA,"34.0","12","6.0","12","0.0","12",NA,"5.8","12",NA,"","1","","",NA,"12.2","59.1","116C8P0"
247 | "SALMON ARM CS","50.703","-119.291","BC","20.0","0","0.2","34.6","0","5.6","0","",,NA,"2.4","0",NA,"","1","",,NA,"11.5","73.6","116FRMN"
248 | "GOLDEN A","51.299","-116.982","BC","18.5","1","1.8","33.5","1","3.5","1","0.0","1",NA,"5.2","1",NA,"0.0","1","","",NA,"26.7","41.1","1173210"
249 | "GOLDEN AIRPORT","51.300","-116.984","BC","18.3","0",NA,"33.8","0","3.3","0","",,NA,"2.6","0",NA,"","1","",,NA,"30.3","40.6","1173220"
250 | "GOLDSTREAM RIVER","51.630","-118.425","BC","18.7","0","2.3","34.0","0","4.0","0","0.0","0",NA,"16.0","0","21.0","0.0","5","","",NA,"24.0","45.5","1173242"
251 | "MICA DAM","52.053","-118.585","BC","17.4","0","1.3","34.0","0","4.5","0","0.0","0",NA,"17.2","0","22.0","0.0","5","","",NA,"49.4","32.1","1175122"
252 | "REVELSTOKE A","50.967","-118.183","BC","18.6","4",NA,"29.0","4","7.4","4","",,NA,"4.4","4",NA,"","2","",,NA,"16.6","32.9","1176745"
253 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","20.1","1",NA,"34.6","1","6.3","0","",,NA,"4.8","1",NA,"","2","",,NA,"14.6","76.2","1176755"
254 | "YOHO PARK","51.443","-116.345","BC","14.5","0",NA,"28.8","0","0.4","0","",,NA,"11.6","0",NA,"","4","",,NA,"109.5","0.3","11790J1"
255 | "YOHO NP OHARA LAKE","51.356","-116.337","BC","12.3","0",NA,"26.5","0","-1.0","0","0.0","0",NA,"26.6","0",NA,"0.0","5","","",NA,"175.4","0.0","117R00H"
256 | "CHETWYND A","55.687","-121.627","BC","15.7","0","1.3","30.5","0","3.0","0","0.0","0",NA,"15.8","0","31.0","0.0","5","","",NA,"80.5","10.4","1181508"
257 | "DAWSON CREEK A","55.742","-120.183","BC","16.4","0",NA,"31.2","0","5.0","0","",,NA,"0.0","3",NA,"","0","",,NA,"57.8","7.8","1182289"
258 | "FORT ST. JOHN A","56.238","-120.740","BC","16.2","3",NA,"30.3","0","5.9","3","0.0","1",NA,"12.0","0",NA,"","1","",,NA,"58.5","8.0","1183001"
259 | "MACKENZIE","55.299","-123.133","BC","16.4","8",NA,"32.0","8","4.4","7","",,NA,"14.5","8",NA,"","3","",,NA,"50.0","13.3","1184791"
260 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","16.1","0",NA,"32.5","0","3.2","0","",,NA,"21.2","0",NA,"","5","",,NA,"76.3","17.5","1184793"
261 | "DEASE LAKE A","58.422","-130.031","BC","12.4","11",NA,"30.2","11","1.3","9","",,NA,"39.2","11",NA,"","7","",,NA,"113.5","1.7","1192341"
262 | "FORT NELSON A","58.836","-122.597","BC","16.9","0",NA,"33.3","0","2.1","0","0.0","0",NA,"12.6","0",NA,"","4","",,NA,"61.2","25.7","1192946"
263 | "FORT NELSON","58.841","-122.574","BC","17.3","0",NA,"33.1","0","2.7","0","",,NA,"15.6","0",NA,"","3","",,NA,"52.3","29.8","1192948"
264 | "FORT NELSON UA","58.841","-122.573","BC","17.1","1",NA,"33.5","1","2.5","1","0.0","1",NA,"22.6","1",NA,"0.0","7","","",NA,"54.1","28.0","1192950"
265 | "TETSA RIVER","58.653","-124.236","BC","12.7","28","0.6","28.0","28","1.0","28","0.0","28",NA,"15.0","28",NA,"0.0","1","","",NA,"16.0","0.0","1195J29"
266 | "DEASE LAKE (AUT)","58.426","-130.025","BC","13.0","1",NA,"30.4","1","-1.5","0","",,NA,"40.6","1",NA,"","8","",,NA,"150.8","1.6","119BLM0"
267 | "ATLIN","59.567","-133.700","BC","13.8","0","1.3","28.0","0","3.0","0","0.0","0",NA,"19.0","0","56.0","0.0","6","","",NA,"133.7","2.0","1200560"
268 | "PLEASANT CAMP","59.450","-136.367","BC","13.0","0","-0.4","31.0","0","2.0","0","0.0","0",NA,"99.1","0","137.0","0.0","14","","",NA,"160.7","4.8","1206197"
269 |
--------------------------------------------------------------------------------