diff --git a/.gitignore b/.gitignore index 143d25c383f5069dd6b301dbba7b88bbfe8246fe..2e504efd7120f00948edadd6d16a8189f0332582 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /data /node_modules -/.vs \ No newline at end of file +/.vs +*.png \ No newline at end of file diff --git a/controllers/gddAccumulatedController.js b/controllers/gddAccumulatedController.js index 2d0a48afe1985fbd6623e4be3c7ae54912642d51..824ee076d4b155dcca3513b526d2772dc786789d 100644 --- a/controllers/gddAccumulatedController.js +++ b/controllers/gddAccumulatedController.js @@ -13,13 +13,11 @@ function send_response(message, gdds, data, res) { }) } -function find(collection, query, projection, temps, res, product) { +function find(collection, query, projection, t_base, res, product) { collection.findOne(query, projection).then(function(data) { var min_temps = data["min_temps"] var max_temps = data["max_temps"] var gdds = []; - - var { t_base, t_max, t_min } = temps; var min_temp = 0 var max_temp = 0 @@ -27,7 +25,7 @@ function find(collection, query, projection, temps, res, product) { var gdd_sum = 0; for (var i = 0; i < min_temps.length; i++) { - gdd_value = utils.calculate_gdd(min_temps[i], t_min, max_temps[i], t_max, t_base, product); + gdd_value = utils.calculate_gdd(min_temps[i], max_temps[i], t_base, product); gdd_sum += gdd_value gdds.push(gdd_sum) } @@ -59,8 +57,6 @@ exports.accumulated_gdd = function (req, res) { } var t_base = 50 - var t_max = 86 - var t_min = 50 errors = [] @@ -80,13 +76,9 @@ exports.accumulated_gdd = function (req, res) { if (req.body.hasOwnProperty("t_base")) { t_base = parseFloat(req.body.t_base); - if (t_base < t_min) { - t_min = t_base; - } } else { - out = utils.product_base_switch(product, errors, t_base, t_min); + out = utils.product_base_switch(product, errors, t_base); t_base = out.t_base; - t_min = out.t_min; errors = out.errors; } @@ -110,16 +102,11 @@ exports.accumulated_gdd = function (req, res) { location: 1, } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } if (year != new Date().getFullYear()) { - find(gdd_collection, query, projection, temps, res, product); + find(gdd_collection, query, projection, t_base, res, product); } else { - find(gdd_current_collection, query, projection, temps, res, product); + find(gdd_current_collection, query, projection, t_base, res, product); } }; @@ -144,8 +131,6 @@ exports.accumulated_normal_gdd = function (req, res) { } var t_base = 50 - var t_max = 86 - var t_min = 50 errors = [] @@ -158,13 +143,9 @@ exports.accumulated_normal_gdd = function (req, res) { if (req.body.hasOwnProperty("t_base")) { t_base = parseFloat(req.body.t_base); - if (t_base < t_min) { - t_min = t_base; - } } else { - out = utils.product_base_switch(product, errors, t_base, t_min); + out = utils.product_base_switch(product, errors, t_base); t_base = out.t_base; - t_min = out.t_min; errors = out.errors; } @@ -188,11 +169,6 @@ exports.accumulated_normal_gdd = function (req, res) { location: 1, } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } - find(gdd_normal_collection, query, projection, temps, res, product); + find(gdd_normal_collection, query, projection, t_base, res, product); }; \ No newline at end of file diff --git a/controllers/gddController.js b/controllers/gddController.js index c1b8adacc7f0ac1ed037532d9f63146058626b49..33c48c9d161b575d52468e1bdd182c58f19a5340 100644 --- a/controllers/gddController.js +++ b/controllers/gddController.js @@ -14,19 +14,17 @@ function send_response(message, gdds, data, res) { }) } -function find(collection, query, projection, temps, res, product) { +function find(collection, query, projection, t_base, res, product) { collection.findOne(query, projection).then(function(data) { var min_temps = data["min_temps"] var max_temps = data["max_temps"] var gdds = []; - - var { t_base, t_max, t_min } = temps; var min_temp = 0 var max_temp = 0 for (var i = 0; i < min_temps.length; i++) { - gdd_value = utils.calculate_gdd(min_temps[i], t_min, max_temps[i], t_max, t_base, product); + gdd_value = utils.calculate_gdd(min_temps[i], max_temps[i], t_base, product); gdds.push(gdd_value) } send_response("GDDs", gdds, data, res); @@ -56,8 +54,6 @@ exports.year_gdd = function (req, res) { } var t_base = 50 - var t_max = 86 - var t_min = 50 errors = [] @@ -77,13 +73,9 @@ exports.year_gdd = function (req, res) { if (req.body.hasOwnProperty("t_base")) { t_base = parseFloat(req.body.t_base); - if (t_base < t_min) { - t_min = t_base; - } } else { - out = utils.product_base_switch(product, errors, t_base, t_min); + out = utils.product_base_switch(product, errors, t_base); t_base = out.t_base; - t_min = out.t_min; errors = out.errors; } @@ -107,16 +99,10 @@ exports.year_gdd = function (req, res) { location: 1, } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } - if (year != new Date().getFullYear()) { - find(gdd_collection, query, projection, temps, res, product); + find(gdd_collection, query, projection, t_base, res, product); } else { - find(gdd_current_collection, query, projection, temps, res, product); + find(gdd_current_collection, query, projection, t_base, res, product); } }; \ No newline at end of file diff --git a/controllers/gddNormalController.js b/controllers/gddNormalController.js index b53a015d9d140b9586f86e93cb63d48d5f1d1e01..6ea874dcd456fc4bcf25d2e57c75c461587b0134 100644 --- a/controllers/gddNormalController.js +++ b/controllers/gddNormalController.js @@ -1,19 +1,17 @@ normals_collection = require('../models/normals.js'); utils = require('../lib/utils'); -function find(collection, query, projection, temps, res, product) { +function find(collection, query, projection, t_base, res, product) { collection.findOne(query, projection).then(function(data) { var min_temps = data["min_temps"] var max_temps = data["max_temps"] var gdds = []; - - var { t_base, t_max, t_min } = temps; var min_temp = 0 var max_temp = 0 for (var i = 0; i < min_temps.length; i++) { - gdd_value = utils.calculate_gdd(min_temps[i], t_min, max_temps[i], t_max, t_base, product); + gdd_value = utils.calculate_gdd(min_temps[i], max_temps[i], t_base, product); gdds.push(gdd_value) } @@ -55,8 +53,6 @@ exports.normal = function (req, res) { } var t_base = 50 - var t_max = 86 - var t_min = 50 errors = [] @@ -69,13 +65,9 @@ exports.normal = function (req, res) { if (req.body.hasOwnProperty("t_base")) { t_base = parseFloat(req.body.t_base); - if (t_base < t_min) { - t_min = t_base; - } } else { - out = utils.product_base_switch(product, errors, t_base, t_min); + out = utils.product_base_switch(product, errors, t_base); t_base = out.t_base; - t_min = out.t_min; errors = out.errors; } @@ -92,11 +84,5 @@ exports.normal = function (req, res) { }) } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } - - find(normals_collection, query, projection, temps, res, product); + find(normals_collection, query, projection, t_base, res, product); }; \ No newline at end of file diff --git a/controllers/minMaxController.js b/controllers/minMaxController.js index 28fbc4cf06b2a9abccb05063ec417716cb834827..188a865219c4398fb233df084a867d14fb959d67 100644 --- a/controllers/minMaxController.js +++ b/controllers/minMaxController.js @@ -1,4 +1,4 @@ -gdd_collection = require('../models/gdd.js'); +normals_collection = require('../models/normals.js'); utils = require('../lib/utils'); function send_response(message, gdds, data, res) { @@ -11,52 +11,41 @@ function send_response(message, gdds, data, res) { }) } -function find(collection, query, projection, temps, res, product) { - var total_years = new Date().getFullYear() - new Date(1981, 0, 1, 0, 0, 0, 0).getFullYear() - 1; - const arr_mean = arr => arr.reduce((a,b) => a + b, 0) / arr.length; - collection.find(query, projection).limit(total_years).then(function(data) { - var minimum_year_data = []; - var maximum_year_data = []; - var minimum_mean = 10000000; - var maximum_mean = 0; - var minimum_year = 0; - var maximum_year = 0; - - var { t_base, t_max, t_min } = temps; - +function find(collection, query, projection, t_base, res, product) { + // var total_years = new Date().getFullYear() - new Date(1981, 0, 1, 0, 0, 0, 0).getFullYear() - 1; + // const arr_mean = arr => arr.reduce((a,b) => a + b, 0) / arr.length; + collection.findOne(query, projection).then(function(data) { - for (var y = 0; y < total_years; y ++){ - var min_temps = data[y]["min_temps"]; - var max_temps = data[y]["max_temps"]; - var gdds = [] - var gdd_sum = 0; - for (var i = 0; i < min_temps.length; i++) { - gdd_value = utils.calculate_gdd(min_temps[i], t_min, max_temps[i], t_max, t_base, product); - gdd_sum += gdd_value; - gdds.push(gdd_sum); + var combined_min_means = data["combined_min_mean"]; + var combined_max_means = data["combined_max_mean"]; + + var min_gdds = []; + var max_gdds = []; + var min_gdd_value = 0; + var max_gdd_value = 0; + var min_gdd_sum = 0; + var max_gdd_sum = 0; + + for (var i = 0; i < combined_min_means.length; i++) { + if (product == "corn") { + max_gdd_value = combined_max_means[i] - t_base; + min_gdd_value = combined_min_means[i] - t_base; + } else { + max_gdd_value = utils.calculated_gdd_mean(combined_max_means[i], t_base); + min_gdd_value = utils.calculated_gdd_mean(combined_min_means[i], t_base); } + min_gdd_sum += min_gdd_value; + max_gdd_sum += max_gdd_value; - var gdd_mean = arr_mean(gdds); - if (gdd_mean <= minimum_mean) { - minimum_year_data = gdds; - minimum_mean = gdd_mean; - minimum_year = data[y]["year"]; - } - if (gdd_mean >= maximum_mean) { - maximum_year_data = gdds; - maximum_mean = gdd_mean; - maximum_year = data[y]["year"]; - } + min_gdds.push(min_gdd_sum); + max_gdds.push(max_gdd_sum); } - res.json({ message: "min and max gdd", - minimum: minimum_year_data, - maximum: maximum_year_data, - minimum_year: minimum_year, - maximum_year: maximum_year, - closest_lon: data[0]["location"]["coordinates"][0], - closest_lat: data[0]["location"]["coordinates"][1] + minimum: min_gdds, + maximum: max_gdds, + closest_lon: data["location"]["coordinates"][0], + closest_lat: data["location"]["coordinates"][1] }); }, function(err) { res.status(500).send({"internal error": err}) @@ -82,8 +71,6 @@ exports.min_max = function (req, res) { } var t_base = 50 - var t_max = 86 - var t_min = 50 errors = [] @@ -95,12 +82,10 @@ exports.min_max = function (req, res) { } - out = utils.product_base_switch(product, errors, t_base, t_min); + out = utils.product_base_switch(product, errors, t_base); t_base = out.t_base; - t_min = out.t_min; errors = out.errors; - if (longitude < -125 || longitude > -66.5) { errors.push({ @@ -116,19 +101,13 @@ exports.min_max = function (req, res) { } var projection = { - min_temps: 1, - max_temps: 1, - location: 1, - year: 1 + // combined_max_mean: 1, + // combined_min_mean: 1, + // location: 1, } - temps = { - t_base: t_base, - t_max: t_max, - t_min: t_min, - } - find(gdd_collection, query, projection, temps, res, product); + find(normals_collection, query, projection, t_base, res, product); }; \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js index 41023ea2946dfb39faaefa3d715ebc028025a59e..de2ef459a5ba458fa37d459a53df7b7bbeaacb62 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,44 +1,36 @@ const gdd = require("../models/gdd"); -function product_base_switch(product, errors, t_base, t_min) { +function product_base_switch(product, errors, t_base) { switch (product) { - case "soybean": case "corn": + case "soybean": case "sunflower": case "tomato": case "sugar_beet": case "peanut": t_base = 50; - t_min = 50; break; case "cotton": t_base = 57.2; - t_min = 57.2; break; case "potato": t_base = 44.6; - t_min = 44.6; // NEED TO ASK ABOUT MIN AND MAX TEMPS IN DAY. SHOULD T_MIN BE SET EQUAL TO T_BASE IF IT IS LESS THAN T_BASE? break; case "wheat": t_base = 41.9; - t_min = 41.9; break; case "pea": case "oat": t_base = 40.1; - t_min = 40.1; break; case "spring_wheat": t_base= 32; - t_min = 32; break; case "rice": t_base = 46.4; - t_min = 46.4; break; case "sorghum": t_base = 46.4; - t_min = 46.4; break; default: errors.push({ @@ -49,25 +41,32 @@ function product_base_switch(product, errors, t_base, t_min) { } return { t_base: t_base, - t_min: t_min, errors: errors } } -function calculate_gdd(min_temp, t_min, max_temp, t_max, t_base, product) { +function calculate_gdd(min_temp, max_temp, t_base, product) { var gdd = 0; if (product == "corn") { - min_temp = min_temp >= t_min ? min_temp : t_min; - max_temp = max_temp >= t_min ? max_temp : t_min; - max_temp = max_temp <= t_max ? max_temp : t_max; - gdd = ((max_temp + min_temp) / 2) - t_base; + min_temp = min_temp >= 50 ? min_temp : 50; + max_temp = max_temp >= 50 ? max_temp : 50; + max_temp = max_temp <= 86 ? max_temp : 86; + mean = ((max_temp + min_temp) / 2); + return mean - t_base; } else { - gdd = ((max_temp + min_temp) / 2) - t_base; - gdd = gdd < 0 ? 0 : gdd; + mean = ((max_temp + min_temp) / 2); + return calculated_gdd_mean(mean, t_base); } return gdd } +function calculated_gdd_mean(mean, t_base) { + var values = mean - t_base; + values = values < 0 ? 0 : values; + return values; +} + module.exports.product_base_switch = product_base_switch; -module.exports.calculate_gdd = calculate_gdd; \ No newline at end of file +module.exports.calculate_gdd = calculate_gdd; +module.exports.calculated_gdd_mean = calculated_gdd_mean; \ No newline at end of file diff --git a/models/normals.js b/models/normals.js index 16fed71ae8c1166443d526828e25b163d6d8073d..b462fae5702b3c9b5dce558e94ee055943fb78f3 100644 --- a/models/normals.js +++ b/models/normals.js @@ -26,6 +26,12 @@ var normalsSchema = mongoose.Schema({ max_temps: { type: Array, }, + combined_max_mean: { + type: Array, + }, + combined_min_mean: { + type: Array, + }, }); var Model = module.exports = mongoose.model('normals', normalsSchema, "normals"); diff --git a/test_server.py b/test_server.py index 856a9f2f1f38dac0c1825811e77027c30513afab..a78a556add0c1afc105b7a79c17f90cfc52a30bf 100644 --- a/test_server.py +++ b/test_server.py @@ -1,6 +1,7 @@ import requests import os import time +import matplotlib.pyplot as plt data = { "latitude": 38.98567, @@ -32,4 +33,18 @@ print (r.status_code) print (r.json()) r = requests.post("http://localhost:4000/api/soybean/minmax", data=data) print (r.status_code) -print (r.json()) \ No newline at end of file +print (r.json()) + +min_gdds = r.json()["minimum"] +max_gdds = r.json()["maximum"] + +r = requests.post("http://localhost:4000/api/soybean/normal/accumulated", data=data) +print (r.status_code) +print (r.json()) + +normals = r.json()["data"] + +plt.plot(list(range(len(normals))), normals, color="black") +plt.plot(list(range(len(normals))), max_gdds, color="orange") +plt.plot(list(range(len(normals))), min_gdds, color="blue") +plt.savefig("test.png", dpi=600) \ No newline at end of file diff --git a/to_mongo.py b/to_mongo.py index dcf98b0b89109b5ad45f09d20f51c7e546fbba2c..02ab4567529cd74a2f361098fd9f7d4eeeb5d9f3 100644 --- a/to_mongo.py +++ b/to_mongo.py @@ -20,98 +20,98 @@ client = MongoClient("mongodb+srv://gdd-server:u8i3icLAJXjZEhTs@cluster0.wdxf4.m db = client["gdd_database"] -gdd = db.gdd +# gdd = db.gdd -gdd.drop() +# gdd.drop() -gdd = db["gdd"] +# gdd = db["gdd"] -resp = gdd.create_index([ ("location", "2dsphere") ]) -resp = gdd.create_index([ ("year", 1) ]) +# resp = gdd.create_index([ ("location", "2dsphere") ]) +# resp = gdd.create_index([ ("year", 1) ]) coords = xr.open_dataset("coords.nc") lat = coords.latitude.data lon = coords.longitude.data lat = lat[::-1] -years = list(range(1981, 2020 + 1)) +# years = list(range(1981, 2020 + 1)) -for year in years: - soy = np.datetime64("%s-01-01" % year) - print (year) - data = xr.open_dataset("data/temps_%s.nc" % year) - x = np.where(~np.isnan(np.nanmean(data.tmin.data, axis=0))) - # x = [(a, b) for a, b in zip(lat_a, lon_a)] # fix to x[0], x[1] when atlas limit removed - # FORCE LOCATIONS TO COLLEGE PARK, LAT 38.99 LON -76.94 BECAUSE OF ATLAS LIMIT +# for year in years: +# soy = np.datetime64("%s-01-01" % year) +# print (year) +# data = xr.open_dataset("data/temps_%s.nc" % year) +# x = np.where(~np.isnan(np.nanmean(data.tmin.data, axis=0))) +# # x = [(a, b) for a, b in zip(lat_a, lon_a)] # fix to x[0], x[1] when atlas limit removed +# # FORCE LOCATIONS TO COLLEGE PARK, LAT 38.99 LON -76.94 BECAUSE OF ATLAS LIMIT - a1 = np.where(38.5 < lat)[0].tolist() - a2 = np.where(lat < 39.5)[0].tolist() - lat_a = np.array(list(set(a1) & set(a2))) +# a1 = np.where(38.5 < lat)[0].tolist() +# a2 = np.where(lat < 39.5)[0].tolist() +# lat_a = np.array(list(set(a1) & set(a2))) - a1 = np.where(-77 < lon)[0].tolist() - a2 = np.where(lon < -76)[0].tolist() - lon_a = np.array(list(set(a1) & set(a2))) +# a1 = np.where(-77 < lon)[0].tolist() +# a2 = np.where(lon < -76)[0].tolist() +# lon_a = np.array(list(set(a1) & set(a2))) - x1 = np.array(np.meshgrid(lat_a, lon_a)).T.reshape(len(lat_a) * len(lon_a), 2).tolist() - x1 = [(z[0], z[1]) for z in x1] - x2 = [(a, b) for a, b in zip(x[0], x[1])] # fix to x = [..... (x[0], x[1])] and all limiting stuff above and below when atlas limit removed +# x1 = np.array(np.meshgrid(lat_a, lon_a)).T.reshape(len(lat_a) * len(lon_a), 2).tolist() +# x1 = [(z[0], z[1]) for z in x1] +# x2 = [(a, b) for a, b in zip(x[0], x[1])] # fix to x = [..... (x[0], x[1])] and all limiting stuff above and below when atlas limit removed - x = list(set(x1) & set(x2)) +# x = list(set(x1) & set(x2)) - tmins = data.tmin.data - tmaxs = data.tmax.data +# tmins = data.tmin.data +# tmaxs = data.tmax.data - # if is_leap_year(year): # extra day in leap year screws everything up +# # if is_leap_year(year): # extra day in leap year screws everything up - # tmin_1 = tmins[:59] - # tmin_2 = tmins[60:] +# # tmin_1 = tmins[:59] +# # tmin_2 = tmins[60:] - # tmax_1 = tmaxs[:59] - # tmin_2 = tmaxs[60:] +# # tmax_1 = tmaxs[:59] +# # tmin_2 = tmaxs[60:] - # tmins = np.concatenate([tmin_1, tmin_2], axis=0) - # tmaxs = np.concatenate([tmax_1, tmin_2], axis=0) +# # tmins = np.concatenate([tmin_1, tmin_2], axis=0) +# # tmaxs = np.concatenate([tmax_1, tmin_2], axis=0) - locs = [] +# locs = [] - count = 0 - for i in tqdm.tqdm(x): - if len(locs) % 100 == 0 and len(locs) != 0: - new_result = gdd.insert_many(locs) - locs = [] +# count = 0 +# for i in tqdm.tqdm(x): +# if len(locs) % 100 == 0 and len(locs) != 0: +# new_result = gdd.insert_many(locs) +# locs = [] - tmin_ = tmins[:, i[0], i[1]] - tmax_ = tmaxs[:, i[0], i[1]] +# tmin_ = tmins[:, i[0], i[1]] +# tmax_ = tmaxs[:, i[0], i[1]] - lat_ = lat[i[0]] - lon_ = lon[i[1]] +# lat_ = lat[i[0]] +# lon_ = lon[i[1]] - a = i +# a = i - t = {} +# t = {} - _id = str(year) + "_" +# _id = str(year) + "_" - _id += str(a[0]) + "_" + str(a[1]) +# _id += str(a[0]) + "_" + str(a[1]) - t["location"] = {"type": "Point", "coordinates": [float(lon_), float(lat_)]} - t["prism_lat"] = int(a[0]) - t["prism_lon"] = int(a[1]) +# t["location"] = {"type": "Point", "coordinates": [float(lon_), float(lat_)]} +# t["prism_lat"] = int(a[0]) +# t["prism_lon"] = int(a[1]) - t["last_date"] = datetime.datetime.strptime(str(soy + np.timedelta64(len(tmin_) - 1, "D")) , "%Y-%m-%d") - t["year"] = int(year) - t["min_temps"] = list([float(a) for a in tmin_]) - t["max_temps"] = list([float(a) for a in tmax_]) - t["_id"] = _id +# t["last_date"] = datetime.datetime.strptime(str(soy + np.timedelta64(len(tmin_) - 1, "D")) , "%Y-%m-%d") +# t["year"] = int(year) +# t["min_temps"] = list([float(a) for a in tmin_]) +# t["max_temps"] = list([float(a) for a in tmax_]) +# t["_id"] = _id - locs.append(t) +# locs.append(t) - count += 1 +# count += 1 - if len(locs) != 0: - new_result = gdd.insert_many(locs) +# if len(locs) != 0: +# new_result = gdd.insert_many(locs) ### 30 YEAR NORMALS ### ### Covers from 1981-2010 ### @@ -134,7 +134,10 @@ ld_min = np.zeros((single_year_min.shape[-2], single_year_min.shape[-1])) ld_max = np.zeros((single_year_min.shape[-2], single_year_min.shape[-1]) ) ld_count = 0 -for year in range(1981, 2010+1): +combined_min_mean = np.zeros((366, 621, 1405)) + 100000 +combined_max_mean = np.zeros((366, 621, 1405)) - 100000 + +for year in range(1981, 2019+1): print (year) data = xr.open_dataset("data/temps_%s.nc" % year) @@ -163,9 +166,19 @@ for year in range(1981, 2010+1): ld_max += tmaxs[59] ld_count += 1 + if year <= 2010: + + single_year_max += tmaxs/30 + single_year_min += tmins/30 + - single_year_max += tmaxs/30 - single_year_min += tmins/30 + mean = (tmins + tmaxs) / 2 + + where_min = np.where(mean <= combined_min_mean) + where_max = np.where(mean >= combined_max_mean) + + combined_max_mean[where_max] = mean[where_max] + combined_min_mean[where_min] = mean[where_min] ld_min = ld_min/ld_count ld_max = ld_max/ld_count @@ -205,6 +218,9 @@ for i in tqdm.tqdm(x): tmin_ = tmins[:, i[0], i[1]] tmax_ = tmaxs[:, i[0], i[1]] + + combined_min_ = combined_min_mean[:, i[0], i[1]] + combined_max_ = combined_max_mean[:, i[0], i[1]] lat_ = lat[i[0]] lon_ = lon[i[1]] @@ -223,6 +239,8 @@ for i in tqdm.tqdm(x): t["min_temps"] = list([float(a) for a in tmin_]) t["max_temps"] = list([float(a) for a in tmax_]) + t["combined_min_mean"] = list([float(a) for a in combined_min_]) + t["combined_max_mean"] = list([float(a) for a in combined_max_]) t["_id"] = _id locs.append(t)