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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more