gpt4 book ai didi

Java : How to do aggregation over a list supporting min, 每组中的最大值、平均值、最后一种聚合

转载 作者:行者123 更新时间:2023-12-01 12:46:30 25 4
gpt4 key购买 nike

我之前已经在 MySQL 本身中完成了此操作,因为这似乎是正确的方法,但我必须进行一些业务逻辑计算,然后需要在结果列表上应用分组,任何建议在 Java 中执行此操作而不妥协性能(看过 lambdaj,似乎由于大量使用代理而变慢,但还没有尝试过)。

List<Item>包含名称、值、unixtimestamp 作为属性,并由数据库返回。每条记录间隔 5 分钟。

我应该能够按动态采样时间(例如 1 小时)进行分组,这意味着必须将每 12 条记录分组为一条记录,然后对每组应用 min、max、avg、last。

任何建议表示赞赏。

[更新] 执行以下操作,但尚未对索引映射值上的每个列表元素进行聚合。如您所见,我创建了一个列表映射,其中 key 是请求的整数表示采样时间(30 是此处请求的采样)。

private List<Item> performConsolidation(List<Item> items) {
ListMultimap<Integer, Item> groupByTimestamp = ArrayListMultimap.create();
List<Item> consolidatedItems = new ArrayList<>();
for (Item item : items) {
groupByTimestamp.put((int)floor(((Double.valueOf(item.getItem()[2])) / 1000) / (60 * 30)), item);
}
return consolidatedItems;
}

最佳答案

这里有一个建议:

public Map<Long,List<Item>> group_items(List<Item> items,long sample_period) {
Map<Long,List<Item>> grouped_result = new HashMap<Long,List<Item>>();
long group_key;

for (Item item: items) {
group_key = item.timestamp / sample_period;
if (grouped_result.containsKey(group_key)) {
grouped_result.get(group_key).add(item);
}
else {
grouped_result.put(group_key, new ArrayList<Item>());
grouped_result.get(group_key).add(item);
}
}
return grouped_result;
}

sample_period 是分组依据的秒数:3600 = 小时,900 = 15 分钟

map 中的键当然可以是相当大的数字(取决于采样周期),但这种分组将保留组的内部时间顺序,即较低的键是按时间顺序排在前面的键。如果我们假设原始列表中的数据按时间顺序排序,我们当然可以获取第一个键的值,然后从键中减去该值。这样我们就可以得到键 0、1 等。在这种情况下,在 for 循环开始之前我们需要:

int减法= items.get(0).timestamp/sample_period;//注意,由于这两个数字都是整数/长整数,所以我们有一个整数除法

然后在 for 循环中:

group_key = items.timestamp/sample_period - 相减;

按照这些思路进行操作将会起作用,即按照您所描述的方式对数据集进行分组。然后您可以将 min max avg 等应用于结果列表。但是,由于这些函数当然必须再次迭代各个组列表,因此最好将这些计算合并到此解决方案中,并让函数返回类似 Map 的内容,其中 Aggregates 是包含 avg、min、max 字段的新类型,然后是该组中的项目列表?至于性能,我认为这是可以接受的。这是一个简单的 O(N) 解决方案。编辑:

好吧,只是想添加一个更完整的解决方案/建议,它还可以计算最小值、最大值和平均值:

public class Aggregate {
public double avg;
public double min;
public double max;

public List<Item> items = new ArrayList<Item>();

public Aggregate(Item item) {
min = item.value;
max = item.value;
avg = item.value;
items.add(item);
}

public void addItem(Item item) {
items.add(item);
if (item.value < this.min) {
this.min = item.value;
}
else if (item.value > this.max) {
this.max = item.value;
}
this.avg = (this.avg * (this.items.size() - 1) + item.value) / this.items.size();
}
}

public Map<Long,Aggregate> group_items(List<Item> items,long sample_period) {

Map<Long,Aggregate> grouped_result = new HashMap<Long,Aggregate>();
long group_key;

long subtract = items.get(0).timestamp / sample_period;
for (Item item: items) {
group_key = items.timestamp / sample_period - subtract;
if (grouped_result.containsKey(group_key)) {
grouped_result.get(group_key).addItem(item);
}
else {
grouped_result.put(group_key, new Aggregate(item));
}
}
return grouped_result;
}

这只是一个粗略的解决方案。我们可能想向聚合等添加更多属性。

关于Java : How to do aggregation over a list supporting min, 每组中的最大值、平均值、最后一种聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24651441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com