IoTDB线性随机区间填充缺失数据DEMO

1、背景

甲方网络异常,采集断了5天,按甲方要求,填补能源月报中数据

2、说明

版本:0.12.2-SNAPSHOT

从本月17号17:35分断 到 22号9点恢复

缺失数据为本月18、19、20、21、22零点首条记录

现对17号首条0点数据,与23号首条0点数据做整合 ,填充缺失5天零点数据。

全部平均太假,浮动区间为平均数的0.8-1.2。各位可自定义

本产品中,数据保留2位小数

3、代码

/**
     * 生成总和确定 一组随机数
     * @param total
     * @param splitCount
     * @param min
     * @param max
     * @return
     */
    public static List<Integer> randomAllocation(int total, int splitCount, int min, int max){
        List<Integer> al = new ArrayList<Integer>();
        Random random = new Random();

        if ((splitCount & 1) == 1) {
            System.out.println("个数" + splitCount + "是奇数,单独生成一个随机数");
            int num = 0;
            do {
                num = random.nextInt(max);

                System.out.println("单个的随机为:" + num);
            } while (num >= max || num <= min);

            total = total - num;
            al.add(num);
        }
        int couples = splitCount >> 1;
        int perCoupleSum = total / couples;

        if ((splitCount & 1) == 1) {
            System.out.println("处理后剩余为:" + total);
        }
        System.out.println("将" + total + "拆分为" + couples + "对,每对总数:" + perCoupleSum);

        for (int i = 0; i < couples; i++) {
            Boolean finish = true;
            int num1 = 0;
            int num2 = 0;
            do {
                num1 = random.nextInt(max);
                num2 = perCoupleSum - num1;
                if (!al.contains(num1) && !al.contains(num2)) {
                    if (i == 0) {
                        num1 = (total - couples * perCoupleSum) + num1;
                    }
                }
            } while (num1 < min || num1 > max || num2 < min || num2 > max);
            al.add(num1);
            al.add(num2);
        }

        int check_num = 0;
        Integer.compare(1, 2);
        al.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        });

        System.out.println(Arrays.toString(al.toArray()));

        for (int x : al) {
            check_num = check_num + x;
        }
        System.out.println("验证总和:" + check_num);

        return al;
    }

    public static Map<String, List<BigDecimal>> read(long start, long end) throws Exception{
        Connection connection = null;
        Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
        connection = DriverManager.getConnection("jdbc:iotdb://XXXXX:6667/", "root", "XXXX");
        Statement statement = connection.createStatement();

        ResultSet resultSet = statement.executeQuery("select first_value(s0) from root.xinsaike.wf01.we* group by (["+start+","+end+"),10m,1d)");

        Map<String, List<BigDecimal>> map = new HashMap<String, List<BigDecimal>>(150);
        List<String> title = new ArrayList<String>(150);
        List<List<BigDecimal>> content = new ArrayList<List<BigDecimal>>(150);

        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        for (int i = 1; i < columnCount; i++) {
            title.add(metaData.getColumnLabel(i+1));
            content.add(new ArrayList<BigDecimal>(3));
        }

        while (resultSet.next()) {
            //迭代当前行,列值
            for (int i = 2;i <= columnCount ; i++) {
                String resultStr = resultSet.getString(i);
                if(null != resultStr){
                    content.get(i-2).add(new BigDecimal(resultStr));
                }else {
                    content.get(i-2).add(new BigDecimal("0"));
                }
            }
        }

        for (int i = 0; i < title.size(); i++) {
            map.put(title.get(i),content.get(i));
        }




        statement.close();
        connection.close();

        return map;

    }
    public static void insert( List<ManyDaysBean> list,long[] timestamps) throws Exception{
        Connection connection = null;
        Class.forName("org.apache.iotdb.jdbc.IoTDBDriver");
        connection = DriverManager.getConnection("jdbc:iotdb://XXXXX:6667/", "root", "XXXXX");


        Statement statement = connection.createStatement();

        for (ManyDaysBean bean : list) {
            String s = bean.getPath();

            BigDecimal temp = new BigDecimal(bean.getStartValue()).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN);
            for (int i = 0; i < timestamps.length; i++) {
                long timestamp = timestamps[i];

                temp = temp.add(new BigDecimal(bean.getResult().get(i)).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN));;
                String sql = "insert into "+s.substring(s.indexOf("(")+1,s.lastIndexOf("."))+"(timestamp,s0) values("+timestamp+","+temp+");";
                System.out.println(sql);
                statement.addBatch(sql);
            }

        }
        statement.executeBatch();
        statement.clearBatch();


    }

@Data
public class ManyDaysBean {

    private String path;
    /**
     * bigdecimal 转 Int
     */
    private Integer startValue;
    /**
     * bigdecimal 转 Int
     */
    private Integer endValue;


    /**
     * end - start
     */
    private Integer total;
    private Integer count;
    private Integer min;
    private Integer max;

    private List<Integer> result;

}

主函数

    public static void main(String[] args) throws Exception{

        //缺失天数的 凌晨2秒时间戳
        long[] timestamps = new long[]{1631894402000L,1631980802000L,1632067202000L,1632153602000L,1632240002000L};
        //切割数量为 缺失天数+1
        int count = timestamps.length+1;


        long start1 = 1631808000000L;
        long end1 = 1631808600000L;

        long start2 = 1632326400000L;
        long end2 = 1632327000000L;


        Map<String, List<BigDecimal>> startMap = read(start1,end1);
        Map<String, List<BigDecimal>> endMap = read(start2,end2);

        List<ManyDaysBean> list = new ArrayList<>(startMap.size());
        for (String s : startMap.keySet()) {

            ManyDaysBean bean = new ManyDaysBean();
            bean.setPath(s);
            bean.setStartValue(DecimalUtil.mul(startMap.get(s).get(0),100).intValue());
            bean.setEndValue(DecimalUtil.mul(endMap.get(s).get(0),100).intValue());

            bean.setTotal(bean.getEndValue() - bean.getStartValue());
            bean.setCount(count);
            bean.setMin((int)(bean.getTotal() /count *0.8));
            bean.setMax((int)(bean.getTotal() /count *1.2)+2);

            System.out.println(bean.getPath());
            System.out.println(bean.getStartValue());
            System.out.println(bean.getEndValue());
            System.out.println(bean.getTotal());
            System.out.println(bean.getMin());
            System.out.println(bean.getMax());

            System.out.println("-------------------------");
            if(bean.getStartValue().equals(0)){
                System.out.println("开始为空");
                continue;
            }
            if(bean.getEndValue() - bean.getStartValue() == 0){
                System.out.println("开始和结束相等");
                continue;
            }

            bean.setResult(randomAllocation(bean.getTotal(),bean.getCount(),bean.getMin(),bean.getMax()));

            list.add(bean);
        }


        insert(list,timestamps);

    }

造假成功,完美解决

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值