从Julia中的数据标记密钥的最后记录
在Julia中处理大数据时,人们认为标记组或ID的最后一条记录的最佳方式是什么 示例数据:从Julia中的数据标记密钥的最后记录,julia,Julia,在Julia中处理大数据时,人们认为标记组或ID的最后一条记录的最佳方式是什么 示例数据: ID|some_value 1011|200 1011|250 1011|100 # <-- I want to flag when I am here... 1012|450 .... 但我认为这不是很有效。有更好的办法吗 不清楚您是如何迭代/使用什么数据结构的。但最简单的方法是迭代并跟踪上一行*: current_row = data[1, 1:end] # first row previ
ID|some_value
1011|200
1011|250
1011|100 # <-- I want to flag when I am here...
1012|450
....
但我认为这不是很有效。有更好的办法吗 不清楚您是如何迭代/使用什么数据结构的。但最简单的方法是迭代并跟踪上一行*:
current_row = data[1, 1:end] # first row
previous_row = current_row
for i in 2:size(data, 1) # for each row
current_row = data[i, 1:end]
if current_row[1] != previous_row[i] # or however you access "ID"
# do something cool with previous_row
end
previous_row = current_row
end
# do something cool with previous_row (last row)
注意:由于数组是按列顺序存储的,而不是按行顺序存储的,因此会出现性能警告,这取决于数据结构。也许你可以使用一些技巧
*假设数据是按ID排序的
如果您使用的数据帧包含未排序的数据,请参阅,也许您希望按ID分组并将
last
应用于每个组。不清楚您是如何迭代/使用什么数据结构的。但最简单的方法是迭代并跟踪上一行*:
current_row = data[1, 1:end] # first row
previous_row = current_row
for i in 2:size(data, 1) # for each row
current_row = data[i, 1:end]
if current_row[1] != previous_row[i] # or however you access "ID"
# do something cool with previous_row
end
previous_row = current_row
end
# do something cool with previous_row (last row)
注意:由于数组是按列顺序存储的,而不是按行顺序存储的,因此会出现性能警告,这取决于数据结构。也许你可以使用一些技巧
*假设数据是按ID排序的
如果您使用的数据帧包含未排序的数据,请参阅,您可能希望按ID分组,并将
last
应用于每个组。这取决于您的优先级。您想要一个花费最少精力编写的解决方案吗?还是你想要极快的版本
请注意,在Julia中,迭代解(为循环编写)通常是计算某些内容的最快方法。假设您的ID列已排序(或至少已分组),快速脏方法将是使用diff:
julia> data = [1011 200
1011 250
1011 100 # <-- I want to flag when I am here...
1012 450]
4x2 Array{Int64,2}:
1011 200
1011 250
1011 100
1012 450
julia> last_values1(A) = A[push!(diff(A[:,1]), 1) .!= 0, 2]
last_values1 (generic function with 1 method)
julia> last_values1(data)
2-element Array{Int64,1}:
100
450
现在我们只是将元素直接推到一个不断增长的阵列上(这甚至可以进一步优化)。这也可以很容易地扩展到其他分析。我们可以将效果与更大的虚假数据集进行比较:
julia> data = [rand(1:1000, 100_000) rand(1:100_000, 100_000)];
idxs = sortperm(data[:, 1])
data = data[idxs, :];
julia> @time last_values1(data);
0.002753 seconds (20 allocations: 2.321 MB)
julia> @time last_values2(data);
0.000551 seconds (14 allocations: 16.500 KB)
julia> last_values1(data) == last_values2(data)
true
因此,在这种情况下,除非您的数据集绝对庞大,否则实际上没有那么大的优势。这取决于您的优先级。您想要一个花费最少精力编写的解决方案吗?还是你想要极快的版本 请注意,在Julia中,迭代解(为循环编写)通常是计算某些内容的最快方法。假设您的ID列已排序(或至少已分组),快速脏方法将是使用diff:
julia> data = [1011 200
1011 250
1011 100 # <-- I want to flag when I am here...
1012 450]
4x2 Array{Int64,2}:
1011 200
1011 250
1011 100
1012 450
julia> last_values1(A) = A[push!(diff(A[:,1]), 1) .!= 0, 2]
last_values1 (generic function with 1 method)
julia> last_values1(data)
2-element Array{Int64,1}:
100
450
现在我们只是将元素直接推到一个不断增长的阵列上(这甚至可以进一步优化)。这也可以很容易地扩展到其他分析。我们可以将效果与更大的虚假数据集进行比较:
julia> data = [rand(1:1000, 100_000) rand(1:100_000, 100_000)];
idxs = sortperm(data[:, 1])
data = data[idxs, :];
julia> @time last_values1(data);
0.002753 seconds (20 allocations: 2.321 MB)
julia> @time last_values2(data);
0.000551 seconds (14 allocations: 16.500 KB)
julia> last_values1(data) == last_values2(data)
true
因此,在这种情况下,除非您的数据集绝对庞大,否则实际上没有那么大的优势