os.path Python, дросселирующий на еврейских именах файлов

Вот код, который все еще векторизован, и он не использует многопоточность. На моем компьютере он более чем в два раза быстрее оригинала, но кое-что еще можно сделать здесь.

Кстати, я серьезно сомневаюсь, что код Matlab особенно оптимизирован, так как происходят некоторые очень расточительные операции - ненужное распределение, ненужные операции (sum(w.*1) действительно плохо, умножение массива на 1 и выделение дополнительного массива в процессе это ужасно расточительно :) Кроме того, вам не нужно выделять какие-либо векторы xx_0_0, xx_1_0 в Matlab, вы можете просто использовать трансляцию, как в Джулии.

Во всяком случае, вот моя первая попытка:

function fit_xlin2(x, y, w)
    regularization = 1.0e-5

    sumwx = (w' * x) + regularization
    sumwy = (w' * y)
    sumwxx = sum(a[1]*a[2]^2 for a in zip(w, x))
    sumwxy = sum(prod, zip(w, x, y))

    wx = w .* x
    xxk_0_0 = sum(w) .- w
    xxk_1_0 = sumwx .- wx
    xxk_1_1 = sumwxx .- wx .* x
    xyk_0 = sumwy .- w .* y
    xyk_1 = sumwxy .- wx .* y

    det = xxk_0_0 .* xxk_1_1 .- xxk_1_0 .* xxk_1_0
    c0  = (xxk_1_1 .* xyk_0  .- xxk_1_0 .* xyk_1)./det
    c1  = (-xxk_1_0 .* xyk_0 .+ xxk_0_0 .* xyk_1)./det

    return c0 .+ c1 .* x
end

Редактировать: Вы можете получить достаточное ускорение, если де-векторизовать основной цикл. Этот код примерно в 17 раз быстрее исходного кода Julia, все еще однопоточный и достаточно читаемый:

function fit_xlin_loop(x, y, w)
    if !(size(x) == size(y) == size(w))
        error("Input vectors must have the same size.")
    end

    regularization = 1.0e-5

    sumw = sum(w)
    sumwx = (w' * x) + regularization
    sumwy = (w' * y)
    sumwxx = sum(a[1]*a[2]^2 for a in zip(w, x))
    sumwxy = sum(prod, zip(w, x, y))

    y_est = similar(x)
    @inbounds for i in eachindex(y_est)
        wx = w[i] * x[i]
        xxk_0_0 = sumw - w[i]
        xxk_1_0 = sumwx - wx
        xxk_1_1 = sumwxx - wx * x[i]
        xyk_0 = sumwy - w[i] * y[i]
        xyk_1 = sumwxy - wx * y[i]

        det = xxk_0_0 * xxk_1_1 - xxk_1_0 * xxk_1_0
        c0  = (xxk_1_1 * xyk_0 - xxk_1_0 * xyk_1) / det
        c1  = (-xxk_1_0 * xyk_0 + xxk_0_0 * xyk_1) / det

        y_est[i] = c0 + c1 * x[i]
    end
    return y_est
end
14
задан Glorfindel 27 February 2019 в 08:01
поделиться

4 ответа

Хм, после некоторого рытья кажется что при предоставлении os.listdir строки unicode, этого вида работ:

files = os.listdir(u'test_source')

for f in files:

    pf = os.path.join(u'test_source', f)
    print pf.encode('ascii', 'replace'), os.path.exists(pf)

===>

test_source\ex True
test_source\joe True
test_source\mie.txt True
test_source\__()'''.txt True
test_source\????.txt True

Некоторые важные наблюдения здесь:

  • Windows XP (как все производные NT) хранит все имена файлов в unicode
  • os.listdir (и подобные функции, как os.walk) должен быть передан строка unicode для работы правильно с путями unicode. Вот кавычка из вышеупомянутой ссылки:

os.listdir (), который возвращает имена файлов, поднимает вопрос: это должно возвратить версию Unicode имен файлов, или это должно возвратить 8-разрядные строки, содержащие закодированные версии? os.listdir () сделает обоих, в зависимости от того, обеспечили ли Вы путь к каталогу как 8-разрядную строку или строку Unicode. При передаче строки Unicode как пути имена файлов будут декодироваться с помощью кодирования файловой системы, и список строк Unicode будет возвращен, в то время как передача 8-разрядного пути возвратит 8-разрядные версии имен файлов.

  • И наконец, print хочет строку ASCII, не unicode, таким образом, путь должен быть закодирован к ASCII.
17
ответ дан 1 December 2019 в 12:53
поделиться

Это работает как очарование с помощью Python 2.5.1 на OS X:

subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True

Возможно, это означает, что это имеет отношение к Windows XP так или иначе?

Править: Я также пытался строками unicode судить имитатора поведение Windows лучше:

for f in os.listdir(u'subdir'):
  pf = os.path.join(u'subdir', f)
  print pf, os.path.exists(pf)

subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True

В Терминале (OS x приложение командной строки запаса), который является. Используя НЕАКТИВНЫЙ это все еще работало, но не распечатало имя файла правильно. Для проверки это действительно - unicode там, я проверил:

>>>os.listdir(u'listdir')[2]
u'\u05e2\u05b4\u05d1\u05b0\u05e8\u05b4\u05d9\u05ea.txt'
1
ответ дан 1 December 2019 в 12:53
поделиться

Это похоже на Unicode по сравнению с проблемой ASCII - os.listdir возвращает список строк ASCII.

Править: Я попробовал его на Python 3.0, также на XP SP2, и os.listdir просто опущенный еврейские имена файлов вместо того, чтобы перечислить их вообще.

Согласно документам, это означает, что не могло декодировать его:

Обратите внимание, что, когда os.listdir () возвращает список строк, имена файлов, которые не могут декодироваться правильно, опущены вместо того, чтобы повысить UnicodeError.

3
ответ дан 1 December 2019 в 12:53
поделиться

Вопросительный знак является более или менее универсальным символом, отображенным, когда unicode символ не может быть представлен в определенном кодировании. Ваша терминальная или интерактивная сессия в соответствии с Windows, вероятно, использует ASCII или ISO-8859-1 или что-то. Таким образом, фактическая строка является unicode, но это переводится в???? при печати к терминалу. Вот почему это работает на PEZ, с помощью OSX.

0
ответ дан 1 December 2019 в 12:53
поделиться
Другие вопросы по тегам:

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