Published
Edited
Mar 2, 2020
3 forks
Importers
166 stars
Insert cell
Insert cell
[
{date: new Date(2012, 0, 1), precipitation: 0},
{date: new Date(2012, 0, 2), precipitation: 10.9},
{date: new Date(2012, 0, 3), precipitation: 0.8},
{date: new Date(2012, 0, 4), precipitation: 20.3}
]
Insert cell
Insert cell
({
date: Float64Array.of(1325404800000, 1325491200000, 1325577600000, 1325664000000),
precipitation: Float64Array.of(0, 10.9, 0.8, 20.3)
})
Insert cell
Insert cell
date
Insert cell
Insert cell
precipitation
Insert cell
Insert cell
Insert cell
objects = Array.from({length}, (_, i) => ({
date: date[i],
precipitation: precipitation[i]
}))
Insert cell
Insert cell
({
date: objects.map(d => d.date),
precipitation: Float64Array.from(objects, d => d.precipitation)
})
Insert cell
Insert cell
function take(values, index) {
return values.constructor.from(index, i => values[i]);
}
Insert cell
Insert cell
take(date, [0, 1, 2])
Insert cell
Insert cell
take(precipitation, [0, 1, 2])
Insert cell
Insert cell
take(date, [2, 1, 2, 1])
Insert cell
Insert cell
function taker(index) {
return values => values.constructor.from(index, i => values[i]);
}
Insert cell
[date, precipitation].map(taker([0, 1, 2]))
Insert cell
Insert cell
function get(i) {
return values => values[i];
}
Insert cell
[date, precipitation].map(get(0))
Insert cell
Insert cell
function range(start, stop, step) {
const n = arguments.length;
start = +start, stop = +stop, step = n < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
return Uint32Array.from({length: Math.ceil((stop - start) / step)}, (_, i) => start + i * step);
}
Insert cell
range(length)
Insert cell
Insert cell
objects.filter(d => d.precipitation > 50)
Insert cell
Insert cell
precipitation.filter(d => d > 50)
Insert cell
Insert cell
take(date, range(length).filter(i => precipitation[i] > 50))
Insert cell
Insert cell
function filter(values, test) {
const I = [], n = values.length;
for (let i = 0; i < n; ++i) {
if (test(values[i], i, values)) {
I.push(i);
}
}
return I;
}
Insert cell
Insert cell
function filteri(values, index, test) {
const I = [], n = index.length;
for (let i = 0; i < n; ++i) {
const j = index[i];
if (test(values[j], j, values)) {
I.push(j);
}
}
return I;
}
Insert cell
Insert cell
take(date, filter(precipitation, d => d > 50))
Insert cell
Insert cell
[date, precipitation].map(taker(filter(precipitation, d => d > 50)))
Insert cell
Insert cell
[date, precipitation].map(taker(filter(date, d => d.getMonth() === 11 && d.getDate() === 25)))
Insert cell
Insert cell
objects.filter(d => d.date.getMonth() === 11 && d.date.getDate() === 25)
Insert cell
Insert cell
precipitation.map(d => d * 0.0393701)
Insert cell
Insert cell
Uint16Array.from(precipitation, d => d * 0.0393701)
Insert cell
Insert cell
objects.map(d => ({
date: d.date,
precipition: d.precipitation * 0.0393701
}))
Insert cell
Insert cell
function slice(...options) {
return array => array.slice(...options);
}
Insert cell
[date, precipitation].map(slice(-10))
Insert cell
Insert cell
function reverse(array) {
return array.slice().reverse();
}
Insert cell
[date, precipitation].map(slice(-10)).map(reverse)
Insert cell
Insert cell
function sort(values, order = ascending) {
return range(values.length).sort((i, j) => order(values[i], values[j]));
}
Insert cell
function sorti(values, index, order = ascending) {
return index.slice().sort((i, j) => order(values[i], values[j]));
}
Insert cell
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
Insert cell
function descending(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
Insert cell
Insert cell
[date, precipitation].map(taker(sort(precipitation, descending).slice(0, 10)))
Insert cell
Insert cell
objects.reduce((p, d) => (d = +d.precipitation) ? p + d : p, 0)
Insert cell
Insert cell
precipitation.reduce((p, d) => (d = +d) ? p + d : p, 0)
Insert cell
Insert cell
function sum(values) {
let sum = 0;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v) sum += v;
}
return sum;
}
Insert cell
Insert cell
function sumi(values, index) {
let sum = 0;
for (let i = 0, n = index.length; i < n; ++i) {
const v = +values[index[i]];
if (v) sum += v;
}
return sum;
}
Insert cell
Insert cell
sum(precipitation)
Insert cell
Insert cell
sum(objects.map(d => d.precipitation))
Insert cell
Insert cell
precipitation.length
Insert cell
Insert cell
function count(values) {
let count = 0;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v === v) ++count;
}
return count;
}
Insert cell
function counti(values, index) {
let count = 0;
for (let i = 0, n = index.length; i < n; ++i) {
const v = +values[index[i]];
if (v === v) ++count;
}
return count;
}
Insert cell
Insert cell
count(precipitation)
Insert cell
[date, precipitation].map(count)
Insert cell
Insert cell
function mean(values) {
return sum(values) / count(values);
}
Insert cell
function meani(values, index) {
return sumi(values, index) / counti(values, index);
}
Insert cell
mean(precipitation)
Insert cell
Insert cell
mean(precipitation.map(d => d > 0))
Insert cell
Insert cell
[temp_min, temp_max].map(mean)
Insert cell
Insert cell
objects.reduce((p, d) => d.precipitation > p.precipitation ? d : p)
Insert cell
Insert cell
precipitation.reduce((p, d) => d > p ? d : p)
Insert cell
Insert cell
function max(values) {
let maxIndex, maxValue = -Infinity;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v > maxValue) maxIndex = i, maxValue = v;
}
return maxIndex;
}
Insert cell
function maxi(values, index) {
let maxIndex, maxValue = -Infinity;
for (let i = 0, n = index.length; i < n; ++i) {
const v = +values[index[i]];
if (v > maxValue) maxIndex = index[i], maxValue = v;
}
return maxIndex;
}
Insert cell
[date, precipitation].map(get(max(precipitation)))
Insert cell
Insert cell
precipitation.reduce((p, d) => p + (d === 0), 0)
Insert cell
function min(values) {
let minIndex, minValue = Infinity;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v < minValue) minIndex = i, minValue = v;
}
return minIndex;
}
Insert cell
function mini(values, index) {
let minIndex, minValue = Infinity;
for (let i = 0, n = index.length; i < n; ++i) {
const v = +values[index[i]];
if (v < minValue) minIndex = index[i], minValue = v;
}
return minIndex;
}
Insert cell
[date, temp_min].map(get(min(temp_min)))
Insert cell
Insert cell
[date, temp_max].map(get(max(temp_max)))
Insert cell
Insert cell
Insert cell
function quantile(values, p) {
values = Float64Array.from(values).filter(number).sort(ascending);
const n = values.length;
if (!n) return NaN;
if (!((p = +p) > 0) || n < 2) return values[0];
if (p >= 1) return values[n - 1];
const i = (n - 1) * p;
const i0 = Math.floor(i);
const v0 = values[i0];
const v1 = values[i0 + 1];
return v0 + (v1 - v0) * (i - i0);
}
Insert cell
function quantilei(values, index, p) {
return quantile(take(values, index), p);
}
Insert cell
Insert cell
quantile(precipitation, 0.75)
Insert cell
Insert cell
function median(values) {
return quantile(values, 0.5);
}
Insert cell
function mediani(values, index) {
return quantilei(values, index, 0.5);
}
Insert cell
median(precipitation)
Insert cell
Insert cell
Insert cell
function top(values, k = 1, order = ascending) {
return range(values.length)
.sort((i, j) => order(values[j], values[i]))
.slice(0, (k = +k) > 0 ? k : 0);
}
Insert cell
function topi(values, index, k = 1, order = ascending) {
return index.slice()
.sort((i, j) => order(values[j], values[i]))
.slice(0, (k = +k) > 0 ? k : 0);
}
Insert cell
Insert cell
[date, precipitation].map(taker(top(precipitation, 5)))
Insert cell
Insert cell
function bottom(values, k = 1, order = ascending) {
return range(values.length)
.sort((i, j) => order(values[i], values[j]))
.slice(0, (k = +k) > 0 ? k : 0);
}
Insert cell
function bottomi(values, index, k = 1, order = ascending) {
return index.slice()
.sort((i, j) => order(values[i], values[j]))
.slice(0, (k = +k) > 0 ? k : 0);
}
Insert cell
Insert cell
[date, temp_min].map(taker(bottom(temp_min, 5)))
Insert cell
Insert cell
function group(keys, value) {
const map = new Map;
for (let i = 0, n = keys.length; i < n; ++i) {
let k = keys[i], v = map.get(k);
if (v === undefined) map.set(k, [i]);
else v.push(i);
}
if (value !== undefined) {
for (const [key, index] of map) {
map.set(key, value(index));
}
}
return map;
}
Insert cell
Insert cell
group(date.map(d => d.getFullYear()))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => sumi(precipitation, i))
Insert cell
Insert cell
group(date.map(d => d.getMonth()), i => meani(precipitation, i))
Insert cell
Insert cell
group(date.map(d => d.getMonth()), i => mediani(precipitation, i))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => counti(precipitation, i))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => [date, temp_min].map(get(mini(temp_min, i))))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => [date, precipitation].map(get(maxi(precipitation, i))))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => take(date, topi(precipitation, i, 5)))
Insert cell
Insert cell
group(date.map(d => d.getFullYear()), i => take(date, bottomi(temp_min, i, 5)))
Insert cell
Insert cell
Insert cell
identity = x => x
Insert cell
number = v => !isNaN(v)
Insert cell
length = date.length
Insert cell
date = data.date
Insert cell
precipitation = data.precipitation
Insert cell
temp_max = data.temp_max
Insert cell
temp_min = data.temp_min
Insert cell
wind = data.wind
Insert cell
data = fetch("https://raw.githubusercontent.com/vega/vega-datasets/530b2f02ebcac4539d292d97da0b57f4d1fcf177/data/seattle-weather.csv")
.then(response => response.text())
.then(csv)
.then(([date, precipitation, temp_max, temp_min, wind, weather]) => {
const length = date.length - 1;
return {
date: Array.from({length}, (_, i) => new Date(date[i + 1])),
precipitation: Float64Array.from({length}, (_, i) => +precipitation[i + 1]),
temp_max: Float64Array.from({length}, (_, i) => +temp_max[i + 1]),
temp_min: Float64Array.from({length}, (_, i) => +temp_min[i + 1]),
wind: Float64Array.from({length}, (_, i) => +wind[i + 1])
};
})
Insert cell
csv = {
const EOL = Symbol("EOL");
const EOF = Symbol("EOF");
const QUOTE = 34;
const NEWLINE = 10;
const RETURN = 13;

function dsv(DELIMITER) {
return function(text) {
const columns = [];
let N = (text = text + "").length;
let I = 0; // current character index
let n = 0; // current line number
let k = 0; // current column number
let t; // current token
let eof = N <= 0; // current token followed by EOF?
let eol = false; // current token followed by EOL?

// Strip the trailing newline.
if (text.charCodeAt(N - 1) === NEWLINE) --N;
if (text.charCodeAt(N - 1) === RETURN) --N;

function token() {
if (eof) return EOF;
if (eol) return eol = false, EOL;

// Unescape quotes.
var i, j = I, c;
if (text.charCodeAt(j) === QUOTE) {
while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
if ((i = I) >= N) eof = true;
else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
return text.slice(j + 1, i - 1).replace(/""/g, "\"");
}

// Find next delimiter or newline.
while (I < N) {
if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
else if (c !== DELIMITER) continue;
return text.slice(j, i) || undefined;
}

// Return last token before EOF.
return eof = true, text.slice(j, N) || undefined;
}

while ((t = token()) !== EOF) {
while (t !== EOL && t !== EOF) {
(columns[k] = (columns[k] || new Array(n)))[n] = t;
t = token();
++k;
}
k = 0;
++n;
}

return columns;
};
}

return dsv(",".charCodeAt(0));
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more