You could try filling the gaps before you aggregate them by month.
USGS published a LS7 SLC-off gap-filling algorithm.
This algorithm was recreated for Google Earth Engine by Noel Gorelick: https://code.earthengine.google.com/d20cba5268ccbe117e2fc1c5fefc33f3
Building upon this Genadii Donchyts changed the algorithm for faster performance: https://code.earthengine.google.com/2ead14966758793579dfb31b94855275
The relevant thread can be found on the Google Earth Engine Developers messaging board (after registration).
For completeness, here is the relevant function from Noel Gorelicks Code:
var MIN_SCALE = 1/3;
var MAX_SCALE = 3;
var MIN_NEIGHBORS = 144;
/* Apply the USGS L7 Phase-2 Gap filling protocol, using a single kernel size. */
var GapFill = function(src, fill, kernelSize) {
var kernel = ee.Kernel.square(kernelSize * 30, "meters", false)
// Find the pixels common to both scenes.
var common = src.mask().and(fill.mask())
var fc = fill.updateMask(common)
var sc = src.updateMask(common)
// Find the primary scaling factors with a regression.
// Interleave the bands for the regression. This assumes the bands have the same names.
var regress = fc.addBands(sc)
regress = regress.select(regress.bandNames().sort())
var fit = regress.reduceNeighborhood(ee.Reducer.linearFit().forEach(src.bandNames()), kernel, null, false)
var offset = fit.select(".*_offset")
var scale = fit.select(".*_scale")
// Find the secondary scaling factors using just means and stddev
var reducer = ee.Reducer.mean().combine(ee.Reducer.stdDev(), null, true)
var src_stats = src.reduceNeighborhood(reducer, kernel, null, false)
var fill_stats = fill.reduceNeighborhood(reducer, kernel, null, false)
var scale2 = src_stats.select(".*stdDev").divide(fill_stats.select(".*stdDev"))
var offset2 = src_stats.select(".*mean").subtract(fill_stats.select(".*mean").multiply(scale2))
var invalid = scale.lt(MIN_SCALE).or(scale.gt(MAX_SCALE))
scale = scale.where(invalid, scale2)
offset = offset.where(invalid, offset2)
// When all else fails, just use the difference of means as an offset.
var invalid2 = scale.lt(MIN_SCALE).or(scale.gt(MAX_SCALE))
scale = scale.where(invalid2, 1)
offset = offset.where(invalid2, src_stats.select(".*mean").subtract(fill_stats.select(".*mean")))
// Apply the scaling and mask off pixels that didn't have enough neighbors.
var count = common.reduceNeighborhood(ee.Reducer.count(), kernel, null, true, "boxcar")
var scaled = fill.multiply(scale).add(offset)
.updateMask(count.gte(MIN_NEIGHBORS))
return src.unmask(scaled, true)
}
var source = ee.Image("LANDSAT/LE7_L1T/LE70440342016075EDC00")
var fill = ee.Image("LANDSAT/LE7_L1T/LE70440342016027EDC00")