大文件快速抽样,大样本快速随机取数--蓄水池算法Reservoir Sampling

如何从超大样本中随机取样,最简单的办法是遍历所有的随机样本并记录下来,然后从中再次取样(两次读样本)。
蓄水池算法思想:先顺序取k个样本,然后从k+1开始根据随机结果看是否替换前面k个样本(遍历一次即可)
蓄水池算法步骤:
总样本:n 抽样数:k
1、创建数组array[k],将前面k个样本放入数组
2、从k+1开始,根据(k+i)产生一个n以内的随机数rand,如果rand小于k,则用k+i的值替换array[rand]的值
3、循环2直到遍历所有文件。

大文件随机抽样代码示例
读大文件的时候按块进行读取效率更高

        public static String[][] sampleFile(String input,int sampleline,String readcode){
    
    
                logger.info("begin to sample file");
                String randfileline[][] = new String[sampleline][2];
                try {
    
    
                        BufferedInputStream bis = new BufferedInputStream
                                        (new FileInputStream(new File(input)));
                BufferedReader in = new BufferedReader
                                (new InputStreamReader(bis,readcode), 10 * 1024 * 1024);// 10M    
                int linenumber = 0;
                while (in.ready()) {
    
    
                    if(linenumber < sampleline){
    
    
                            randfileline[linenumber][0] = String.valueOf(linenumber);
                            randfileline[linenumber][1] = in.readLine();
                    }
                    else{
    
    
                            int rand = (int)(Math.random() * linenumber);
                            String line = in.readLine();
                            if(rand < sampleline){
    
    
                                    randfileline[rand][0] = String.valueOf(linenumber);
                                randfileline[rand][1] = line;
                            }
                    }
                    linenumber++;
            }
                in.close();
                } catch ( IOException e) {
    
    
                        ScanClientUtils.getClientLog().error(e.getMessage()+"\n" + ScanClientUtils.printStack(e.getStackTrace()));
                }
                logger.info("finish sample file");
                return randfileline;
        }

猜你喜欢

转载自blog.csdn.net/shyrainxy/article/details/114143100