Преобразование массива CartesianIndex в 2D-матрицу в Julia

Я считаю, что файл с отображением памяти будет самым быстрым решением. Я попробовал четыре функции: функцию, отправленную OP (opcount); простая итерация по строкам в файле (simplecount); readline с картографированной памятью (mmap) (mapcount); и решение для считывания буфера, предложенное Николаем Харечко (bufcount).

Я выполнял каждую функцию пять раз и вычислял среднее время выполнения для текстового файла с 1,2 млн. строк.

Windows XP, Python 2.5, 2 ГБ оперативной памяти, процессор AMD 2 ГГц

Вот мои результаты:

mapcount : 0.465599966049
simplecount : 0.756399965286
bufcount : 0.546800041199
opcount : 0.718600034714

Изменить: номера для Python 2.6:

mapcount : 0.471799945831
simplecount : 0.634400033951
bufcount : 0.468800067902
opcount : 0.602999973297

Таким образом, стратегия чтения буфера, по-видимому, является самой быстрой для Windows / Python 2.6

Вот код:

from __future__ import with_statement
import time
import mmap
import random
from collections import defaultdict

def mapcount(filename):
    f = open(filename, "r+")
    buf = mmap.mmap(f.fileno(), 0)
    lines = 0
    readline = buf.readline
    while readline():
        lines += 1
    return lines

def simplecount(filename):
    lines = 0
    for line in open(filename):
        lines += 1
    return lines

def bufcount(filename):
    f = open(filename)                  
    lines = 0
    buf_size = 1024 * 1024
    read_f = f.read # loop optimization

    buf = read_f(buf_size)
    while buf:
        lines += buf.count('\n')
        buf = read_f(buf_size)

    return lines

def opcount(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1


counts = defaultdict(list)

for i in range(5):
    for func in [mapcount, simplecount, bufcount, opcount]:
        start_time = time.time()
        assert func("big_file.txt") == 1209138
        counts[func].append(time.time() - start_time)

for key, vals in counts.items():
    print key.__name__, ":", sum(vals) / float(len(vals))
0
задан phg 18 January 2019 в 17:50
поделиться

2 ответа

Простой и общий способ -

julia> as_ints(a::AbstractArray{CartesianIndex{L}}) where L = reshape(reinterpret(Int, a), (L, size(a)...))
as_ints (generic function with 1 method)

julia> as_ints(indx)
2×9 reshape(reinterpret(Int64, ::Array{CartesianIndex{2},1}), 2, 9) with eltype Int64:
 1  3  4  1  2  4  1  1  4
 2  2  2  3  3  3  4  5  5

. Это работает для любой размерности, делая первое измерение индексом в CartesianIndex.

0
ответ дан tholy 18 January 2019 в 17:50
поделиться

Одним из возможных способов является hcat(getindex.(indx, 1), getindex.(indx,2))

julia> @btime hcat(getindex.($indx, 1), getindex.($indx,2))
  167.372 ns (6 allocations: 656 bytes)
10×2 Array{Int64,2}:
 4  1
 3  2
 4  2
 1  3
 4  3
 5  3
 2  4
 5  4
 1  5
 4  5

Однако, обратите внимание, что вам не нужно - и, следовательно, вероятно, не должно - привести ваши индексы в форму 2D-матрицы. Вы можете просто сделать

PyPlot.scatter(getindex.(indx, 1), getindex.(indx, 2))
0
ответ дан crstnbr 18 January 2019 в 17:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: