从3000W行的数据取出前50

本文介绍了一种在有限内存条件下,从大规模无序数据集中选取前50个最大ID的有效算法。通过使用缓冲区和Top数组,结合排序及二分查找技巧,实现了一个既节省内存又高效的数据筛选方案。

一个数据文件,有3000W行,每行有一个id号,文件内容无任何排序。
现在让你把id前 TOP 位取出来, TOP = 50.

要求:你的程序最多能吃2G的内存,其他不限,要求考虑io/cup最优。

解决思路:

1 建一个top_array, 长度为50.
2 再建一个buffer, 长度为2^20 (1G)
3 循环开始
4   读取文件到buffer,直到buffer满为止
5   将Buffer的前50位读到top_array
7   将top_array排序,按照id升序
6   循环开始
7      接着读取buffer的下一位
       如果比最后一个还大,next;
        否则,插入到top_array相应位置,并删除最后一个。
    循环到Buffer全部读完为止

9  循环到文件读完为止

当然对to_arary进行插入的时候,用2分法,当然数据结构如果用最小堆/最大堆,也是一样的。

整体时间应该是

nlog(m)

posted on 2011-09-21 01:15  之乎者也2011 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/wrmfw/archive/2011/09/21/2183019.html

### 回答1: 使用golang读取超大Excel可以使用第三方库"github.com/360EntSecGroup-Skylar/excelize"。它支持读取XLSX格式的Excel文件。 读取Excel文件的方式如下: ``` package main import ( "fmt" "github.com/360EntSecGroup-Skylar/excelize" ) func main() { f, err := excelize.OpenFile("./test.xlsx") if err != nil { fmt.Println(err) return } // 读取指定sheet中的数据 rows := f.GetRows("Sheet1") for _, row := range rows { for _, colCell := range row { fmt.Print(colCell, "\t") } fmt.Println() } } ``` 随机取20W数据可以使用rand包来实现。在读取Excel文件之后,可以使用rand.Perm函数来生成随机数组,然后根据随机数组中的索引来取出数据。 代码示例如下: ``` package main import ( "fmt" "github.com/360EntSecGroup-Skylar/excelize" "math/rand" "time" ) func main() { f, err := excelize.OpenFile("./test.xlsx") if err != nil { fmt.Println(err) return } // 读取指定sheet中的数据 rows := f.GetRows("Sheet1") rand.Seed(time.Now().UnixNano()) // 随机取20W数据 numRows := len(rows) randIndex := rand.Perm(numRows)[:20000] for _, index := range randIndex { row := rows[index] for _, colCell := range row { fmt.Print(colCell, "\t") } fmt.Println() } } ``` 这里虽然给出了一个例子,但是对于100列100W数据来说,用上述方式读取性能可能会有影响,建议考虑到数 ### 回答2: 使用golang读取超大Excel文件并随机获取其中的20W数据,可以通过以下步骤: 1. 使用go语言中的Excel文件处理库(如excelize)打开Excel文件。 2. 获取Excel文件的数和列数。 3. 根据数随机生成20W个不重复的索引值,并将这些索引值存储在一个切片中。 4. 遍历切片中的索引值,读取对应数据。 5. 将读取到的数据保存到一个新的Excel文件中,作为结果输出。 以下是一个示例代码,用于演示如何使用golang读取超大Excel文件并随机获取20W数据: ```go package main import ( "fmt" "math/rand" "github.com/xuri/excelize/v2" ) func main() { // 打开Excel文件 f, err := excelize.OpenFile("path/to/large_excel.xlsx") if err != nil { fmt.Println(err) return } // 获取Excel文件的数和列数 rows, _ := f.GetRows("Sheet1") rowCount := len(rows) colCount := len(rows[0]) // 创建一个切片用于存储随机生成的索引值 var randomIndexes []int // 随机生成20W个不重复的索引值 for i := 0; i < 200000; { index := rand.Intn(rowCount) // 如果生成的索引值已存在于切片中,则重新生成 if !contains(randomIndexes, index) { randomIndexes = append(randomIndexes, index) i++ } } // 创建一个新的Excel文件用于保存随机获取到的数据 newFile := excelize.NewFile() newSheet := "RandomData" // 遍历随机生成的索引值,读取对应数据并保存到新的Excel文件中 for i, index := range randomIndexes { for j := 0; j < colCount; j++ { cell, _ := f.GetCellValue("Sheet1", getCellName(j, index)) newFile.SetCellValue(newSheet, getCellName(j, i), cell) } } // 保存新的Excel文件 err = newFile.SaveAs("path/to/random_data.xlsx") if err != nil { fmt.Println(err) return } fmt.Println("随机数据已保存到新的Excel文件中") } // 判断切片中是否包含某个值 func contains(s []int, e int) bool { for _, v := range s { if v == e { return true } } return false } // 根据列索引和索引获取对应的单元格名称 func getCellName(colIndex, rowIndex int) string { colName := string('A' + colIndex) return fmt.Sprintf("%s%d", colName, rowIndex+1) } ``` 在上述示例中,使用`excelize`库打开Excel文件并获取数和列数。然后,通过随机生成不重复的索引值来模拟获取随机数据。最后,将读取到的数据保存到一个新的Excel文件中。 请根据实际需求修改代码中的文件路径和列数等参数。注意,读取和保存超大Excel文件可能会消耗大量的内存和时间,请确保系统资源充足。 ### 回答3: 使用golang读取超大Excel文件,并随机选择其中20万数据的方法如下: 1. 首先,我们需要安装和导入golang对Excel文件操作的包,推荐使用github.com/tealeg/xlsx包。首先使用以下命令安装该包: go get github.com/tealeg/xlsx 2. 导入所需的包: import ( "github.com/tealeg/xlsx" "math/rand" ) 3. 创建一个Excel文件对象: file, err := xlsx.OpenFile("your_excel_file.xlsx") if err != nil { log.Fatal(err) } 4. 选择要读取的工作表: sheet := file.Sheets[0] 5. 获取工作表中的所有: rows := sheet.Rows 6. 计算工作表中总共有多少数据: totalRows := len(rows) 7. 创建一个存储随机索引的切片: randIndexes := rand.Perm(totalRows)[:200000] 8. 遍历切片中的随机索引,读取并处理对应数据: for _, rowIndex := range randIndexes { row := rows[rowIndex] // 处理数据 } 以上步骤就可以使用golang读取超大Excel文件并随机选择20万数据。这里使用了第三方包github.com/tealeg/xlsx,在第4步我们选择了要读取的工作表,在第5步通过Sheet对象的Rows属性获取了所有数据,在第6步我们计算了总共有多少数据。在第7步我们使用rand.Perm函数生成了一个随机排列的数字切片,然后根据切片中的索引获取对应的数据,处理数据的部分可以根据具体需求进编写。通过这种方式,我们可以读取超大Excel文件中的随机数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值