搜索两个日期之间所有日期的平均温度 [英] Searching for average temperature for all dates between two dates

查看:77
本文介绍了搜索两个日期之间所有日期的平均温度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在试图弄清楚如何计算一天的平均温度.该日通常有24个测量值,00:00 01:00 ...等.文件中包含除以';'的信息.像这样:

  2020-12-30; 18:00:00; 1.9; G2020-12-30; 19:00:00; 1.3; G2020-12-30; 20:00:00; 1.1; G2020-12-30; 21:00:00; 1.0; G2020-12-30; 22:00:00; 1.1; G2020-12-30; 23:00:00; 1.3; G2020-12-31; 00:00:00; 1.1; G2020-12-31; 01:00:00; 1.4; G2020-12-31; 02:00:00; 1.9; G2020-12-31; 03:00:00; 1.9; G2020-12-31; 04:00:00; 2.4; G 

我设法将数据存储在构造类型为Data的列表中:在这里,我读取文件并调用构造函数以创建一个带有以下信息的对象,即LocalDateTime,Degrees,无论测量是否批准.

  public void loadData(String filePath)抛出IOException {List< String>fileData = Files.readAllLines(Paths.get(filePath));对于(String fileDatum:fileData){List< String>list = Arrays.asList(fileDatum.split(;")));LocalDateTime localDateTime = LocalDateTime.of(LocalDate.parse(list.get(0)),LocalTime.parse(list.get(1)));double temp = Double.parseDouble(list.get(2));字符串kontroll = list.get(3);数据数据=新数据(localDateTime,kontroll,temp);vaderData.add(data);}} 

这是我要计算一天的平均温度的地方.我设法进行了一天的计算,但是我真的不了解如何继续进行第二天而不必再次遍历整个列表.我也尝试过使用Collectors类,但是那里也没有运气.

 公共列表< String>averageTemperatures(LocalDate dateFrom,LocalDate dateTo){双和= 0;int count = 0;对于(数据平均值:vaderData){如果(dateFrom.isEqual(average.getDate().toLocalDate())){sum = sum + average.getTemp();数++;}}/*映射< LocalDate,Double>平均温度= vaderData.stream().filter(数据->!Data.getDate().toLocalDate().isAfter(dateTo)&&!Data.getDate().toLocalDate().isBefore(dateFrom)).collect(Collectors.groupingBy(Data :: getDate,Collectors.averagingDouble(Data :: getTemp)));*/返回null;} 

解决方案

如果您想按日获取某个范围内的平均值,则可以使用流api进行分组,过滤和映射来执行以下操作:

  Map< LocalDate,Double>平均值= vaderData.stream().collect(Collectors.groupingBy(d-> d.localDateTime.toLocalDate())).entrySet()//地图项集,键为本地日期,值为数据列表.stream()//地图条目流//进行过滤,以便仅从<和<被认为.filter(e->(e.getKey().isEqual(from)|| e.getKey().isAfter(from))&& e.getKey().isBefore(to))//映射条目,使键为本地日期,值为该日的平均温度.map(e->新的AbstractMap.SimpleEntry<>(e.getKey(),e.​​getValue().stream().mapToDouble(d-> d.temp).平均().orElse(Double.NaN)))//将其全部收集为地图,以key为日,以value为平均值.collect(Collectors.toMap(AbstractMap.SimpleEntry :: getKey,AbstractMap.SimpleEntry :: getValue)); 

假设:

数据类定义如下

  class数据{最后的LocalDateTime localDateTime;最终String kontroll;最终双温度;数据(LocalDateTime localDateTime,字符串控制,双温度){this.localDateTime = localDateTime;this.kontroll = kontroll;this.temp = temp;}} 

上面使用的from/to参数类似于

  LocalDate from = LocalDate.parse("2020-12-30");LocalDate = LocalDate.parse("2020-12-31"); 

它们是这样的,即from是包容性的,而to是排斥性的.

使用以上输入,您将获得

  {2020-12-30 = 1.2833333333333334} 

使用提供的数据对应于2020-12-30的平均温度.

修改

从注释中获取计数和其他信息,请查看 summaryStatistics()方法.此处的更多信息: DoubleSummaryStatistics .

示例

使用 summaryStatistics mapToDouble 位之后的

而不是 average()处,您将具有最小值,最大值,计数,总和和平均.

此时的返回类型不再是 Map< LocalDate,Double> ,而将是 Map< LocalDate,DoubleSummaryStatistics> .>

I'm currently trying to figure out how to calculate the average temperature for a day. The day usually has 24 measurements, 00:00 01:00... etc. The file contains information divided by ';'. Like this:

2020-12-30;18:00:00;1.9;G
2020-12-30;19:00:00;1.3;G
2020-12-30;20:00:00;1.1;G
2020-12-30;21:00:00;1.0;G
2020-12-30;22:00:00;1.1;G
2020-12-30;23:00:00;1.3;G
2020-12-31;00:00:00;1.1;G
2020-12-31;01:00:00;1.4;G
2020-12-31;02:00:00;1.9;G
2020-12-31;03:00:00;1.9;G
2020-12-31;04:00:00;2.4;G

I managed to store the data in a List of the constructed type Data: This is where I read the file and call the constructor to create an object with the following information, LocalDateTime, Degrees, whether the measurement was approved or not.

public void loadData(String filePath) throws IOException {
    List<String> fileData = Files.readAllLines(Paths.get(filePath));
    for (String fileDatum : fileData) {
        List<String> list = Arrays.asList(fileDatum.split(";"));
        LocalDateTime localDateTime = LocalDateTime.of(
                LocalDate.parse(list.get(0)), LocalTime.parse(list.get(1)));
        double temp = Double.parseDouble(list.get(2));
        String kontroll = list.get(3);
        Data data = new Data(localDateTime, kontroll, temp);
        vaderData.add(data);
    }
}

This is where I am trying to calculate the average temperature of a day. I manage to calculate for one day, but don't really understand how I can go on to the next day without having to iterate the entire list again. I also experimented with using the Collectors class but had no luck there neither.

public List<String> averageTemperatures(LocalDate dateFrom,
                                        LocalDate dateTo) {
    double sum = 0;
    int count = 0;
    for (Data average : vaderData) {
        if (dateFrom.isEqual(average.getDate().toLocalDate())) {
            sum = sum + average.getTemp();
            count++;
        }
    }
    /*
    Map<LocalDate, Double> Averagetemperature = vaderData.stream()
            .filter(Data -> !Data.getDate().toLocalDate().isAfter(dateTo)
                    && !Data.getDate().toLocalDate().isBefore(dateFrom))
            .collect(Collectors.groupingBy(Data::getDate,
                    Collectors.averagingDouble(Data::getTemp)));
    */
    return null;
}

解决方案

If you want to get averages by day in a range you can use the stream api with grouping, filtering and mapping to do something like this:

Map<LocalDate, Double> averages = vaderData.stream()
        .collect(Collectors.groupingBy(d -> d.localDateTime.toLocalDate()))
        .entrySet() // set of map entries with key as local date and value as list of data
        .stream() // stream of map entries
        // filter such that only dates >= from and < to are considered
        .filter(e -> (e.getKey().isEqual(from) || e.getKey().isAfter(from)) && e.getKey().isBefore(to))
        // map entries such that key is local date and value is average temp for that day
        .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue().stream()
                .mapToDouble(d -> d.temp)
                .average()
                .orElse(Double.NaN)))
        // collect it all as a map with key as the day and value as the average
        .collect(Collectors.toMap(
                AbstractMap.SimpleEntry::getKey,
                AbstractMap.SimpleEntry::getValue));

Assumptions:

The data class is defined as follows

class Data {
    final LocalDateTime localDateTime;
    final String kontroll;
    final double temp;

    Data(LocalDateTime localDateTime, String kontroll, double temp) {
        this.localDateTime = localDateTime;
        this.kontroll = kontroll;
        this.temp = temp;
    }
}

The from / to parameters used in the above are something like

LocalDate from = LocalDate.parse("2020-12-30");
LocalDate to = LocalDate.parse("2020-12-31");

And they are such that from is inclusive and to is exclusive.

With the above input you'll get

{2020-12-30=1.2833333333333334}

Corresponding with the average temperature for 2020-12-30 with the provided data.

Edit

From the comments, to get counts and other information, look at the summaryStatistics() method. More info here: DoubleSummaryStatistics.

Example

after the mapToDouble bit, instead of average(), with summaryStatistics you would have information for min, max, count, sum and average.

The return type on it at that point isn't a Map<LocalDate, Double> anymore, it would be a Map<LocalDate, DoubleSummaryStatistics>.

这篇关于搜索两个日期之间所有日期的平均温度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆