如何将大型 julia DataFrame 分区为箭头文件并在读取数据时按顺序处理每个分区
How to partition a large julia DataFrame to an arrow file and process each partition sequentially when reading the data
我在 Julia 中使用非常大的数据帧,导致在对数据进行连接和其他操作时出现内存不足错误。幸运的是,数据可以在标识符列上进行分区。我想使用构建到 Arrow.jl 中的记录批处理功能来持久化分区 DataFrame,然后依次读取和处理每个记录批处理。我已设法使以下内容正常工作,但无法在读取数据时恢复原始 DataFrame。在读回数据时,我得到一个 DataFrame,其中每列中的所有数据都是原始分区中的数据数组。我不知道我的问题是我一开始是如何创建分区的,还是我是如何读回数据的:
using Random
using DataFrames
using Arrow
function nextidrange(minId, maxId, batchsize, i)
fromId = minId + batchsize * (i-1)
toId = min(maxId, (minId + batchsize * i)-1)
return fromId, toId
end
minId = 1
maxId = 1000
idrange = (maxId - minId) + 1
df = DataFrame(ID=minId:maxId, B=rand(idrange), C=randstring.(fill(5,idrange)));
batchsize = 100
batches = ceil(Int32, idrange / batchsize)
partitions = Array{SubDataFrame}(undef, 0)
for i = 1:batches
fromId, toId = nextidrange(minId, maxId, batchsize, i)
push!(partitions, filter([:ID] => x -> fromId <= x <= toId, df; view = true))
end
io = IOBuffer()
Arrow.write(io, partitions)
seekstart(io)
batches = Arrow.Stream(io)
for b in batches
bt = b |> DataFrame
println("Rows = $(nrow(bt))")
end
对于每个记录批次,我期望一个包含三列和 100 行数据的 DataFrame。
实施注意事项:在实际数据中,标识符值可能存在差距。我考虑过使用 JuliaDB,但 DataFrames 似乎得到了更好的维护和支持。
我已经解决了我的问题,像这样:
using Random
using DataFrames
using Arrow
using Tables
function nextidrange(minId, maxId, batchsize, i)
fromId = minId + batchsize * (i-1)
toId = min(maxId, (minId + batchsize * i)-1)
return fromId, toId
end
minId = 1
maxId = 1000
idrange = (maxId - minId) + 1
df = DataFrame(ID=minId:maxId, B=rand(idrange), C=randstring.(fill(5,idrange)));
batchsize = 100
numbatches = ceil(Int32, idrange / batchsize)
partitions = Array{SubDataFrame}(undef, 0)
for i = 1:numbatches
fromId, toId = nextidrange(minId, maxId, batchsize, i)
push!(partitions, filter([:ID] => x -> fromId <= x <= toId, df; view = true))
end
io = IOBuffer()
Arrow.write(io, Tables.partitioner(partitions))
seekstart(io)
recordbatches = Arrow.Stream(io)
ab = Array{DataFrame}(undef,0)
for b in recordbatches
bt = b |> DataFrame
println("Rows = $(nrow(bt))")
push!(ab,bt)
end
问题是 DataFrame 视图数组应该放在对 Tables.partitioner
的调用中
我在 Julia 中使用非常大的数据帧,导致在对数据进行连接和其他操作时出现内存不足错误。幸运的是,数据可以在标识符列上进行分区。我想使用构建到 Arrow.jl 中的记录批处理功能来持久化分区 DataFrame,然后依次读取和处理每个记录批处理。我已设法使以下内容正常工作,但无法在读取数据时恢复原始 DataFrame。在读回数据时,我得到一个 DataFrame,其中每列中的所有数据都是原始分区中的数据数组。我不知道我的问题是我一开始是如何创建分区的,还是我是如何读回数据的:
using Random
using DataFrames
using Arrow
function nextidrange(minId, maxId, batchsize, i)
fromId = minId + batchsize * (i-1)
toId = min(maxId, (minId + batchsize * i)-1)
return fromId, toId
end
minId = 1
maxId = 1000
idrange = (maxId - minId) + 1
df = DataFrame(ID=minId:maxId, B=rand(idrange), C=randstring.(fill(5,idrange)));
batchsize = 100
batches = ceil(Int32, idrange / batchsize)
partitions = Array{SubDataFrame}(undef, 0)
for i = 1:batches
fromId, toId = nextidrange(minId, maxId, batchsize, i)
push!(partitions, filter([:ID] => x -> fromId <= x <= toId, df; view = true))
end
io = IOBuffer()
Arrow.write(io, partitions)
seekstart(io)
batches = Arrow.Stream(io)
for b in batches
bt = b |> DataFrame
println("Rows = $(nrow(bt))")
end
对于每个记录批次,我期望一个包含三列和 100 行数据的 DataFrame。 实施注意事项:在实际数据中,标识符值可能存在差距。我考虑过使用 JuliaDB,但 DataFrames 似乎得到了更好的维护和支持。
我已经解决了我的问题,像这样:
using Random
using DataFrames
using Arrow
using Tables
function nextidrange(minId, maxId, batchsize, i)
fromId = minId + batchsize * (i-1)
toId = min(maxId, (minId + batchsize * i)-1)
return fromId, toId
end
minId = 1
maxId = 1000
idrange = (maxId - minId) + 1
df = DataFrame(ID=minId:maxId, B=rand(idrange), C=randstring.(fill(5,idrange)));
batchsize = 100
numbatches = ceil(Int32, idrange / batchsize)
partitions = Array{SubDataFrame}(undef, 0)
for i = 1:numbatches
fromId, toId = nextidrange(minId, maxId, batchsize, i)
push!(partitions, filter([:ID] => x -> fromId <= x <= toId, df; view = true))
end
io = IOBuffer()
Arrow.write(io, Tables.partitioner(partitions))
seekstart(io)
recordbatches = Arrow.Stream(io)
ab = Array{DataFrame}(undef,0)
for b in recordbatches
bt = b |> DataFrame
println("Rows = $(nrow(bt))")
push!(ab,bt)
end
问题是 DataFrame 视图数组应该放在对 Tables.partitioner