在Julia中,如何将ASCII小数列表转换为字符串?

Dea*_*ton 3 ascii bioinformatics data-conversion julia

tldr:我想转换[125, 119, 48, 126, 40]为输出字符串,}w0~(


举一个真实的例子,我正在使用fastq格式的序列数据(这是导入的库的链接)。

cat example.fastq 输出以下内容:

@some/random/identifier
ACTAG
+
}w0~(
Run Code Online (Sandbox Code Playgroud)

下面的julia代码演示了如何读取fastq文件:

import BioSequences.FASTQ


fastq_stream = FASTQ.Reader(open("example.fastq", "r"))
for record in fastq_stream
    # Still need to learn, why this offset of 33?
    println(
        Vector{Int8}(FASTQ.quality(record, :sanger)) .+ 33
    )
    println(
        String(FASTQ.sequence(record))
    )
    println(
        String(FASTQ.identifier(record))
    )
    break
end
close(fastq_stream)
Run Code Online (Sandbox Code Playgroud)

此代码显示以下内容:

[125, 119, 48, 126, 40]
ACTAG
some/random/identifier
Run Code Online (Sandbox Code Playgroud)

我不想将此信息存储在列表中。我希望将其转换为字符串。所以我在这里寻找的输出是:

}w0~(
ACTAG
some/random/identifier
Run Code Online (Sandbox Code Playgroud)

Prz*_*fel 6

julia> String(UInt8.([125, 119, 48, 126, 40]))
"}w0~("
Run Code Online (Sandbox Code Playgroud)

说明

在Julia中,字符串是使用一组字节构造的。如果您使用的是ASCII,那么字符字节映射就很简单,您可以直接处理原始数据(这也是最快的方法)。

请注意,由于Julia字符串是不可变的,因此从原始字节创建字符串时,初始字节不可用-这也意味着在String创建过程中不会复制任何数据。看下面的例子:

julia> mybytes = UInt8.([125, 119, 48, 126, 40]);

julia> mystring = String(mybytes)
"}w0~("

julia> mybytes
0-element Array{UInt8,1}
Run Code Online (Sandbox Code Playgroud)

业绩说明

StringJulia中的未被内部化。在分析方案中,请始终考虑使用Symbols而不是Strings。在某些情况下,使用temperature=:hot代替temperature="hot"可能意味着执行时间缩短了3倍。

编辑-性能测试

julia> using Random, BenchmarkTools;Random.seed!(0);

bb = rand(33:126,1000);

julia> @btime join(Char.($bb));
  31.573 ?s (13 allocations: 6.56 KiB)

julia> @btime String(UInt8.($bb));
  711.111 ns (2 allocations: 2.13 KiB)
Run Code Online (Sandbox Code Playgroud)

String(UInt8.($bb)) 快40倍以上,并占用内存的1/3


Dea*_*ton 0

我现在找到了一个可行的解决方案。我确信有更有效的解决方案。

join(Char(i) for i in Vector{Int8}(FASTQ.quality(record, :sanger)) .+ 33)产生我需要的输出。