У меня есть итератор чисел, например, объект файла:
f = open("datafile.dat")
теперь я хочу вычислить:
mean = get_mean(f)
sigma = get_sigma(f, mean)
Какова лучшая реализация? Предположим, что файл является большим, и я хотел бы постараться не читать его дважды.
Если вы хотите выполнить итерацию один раз, вы можете написать свою функцию sum:
def mysum(l):
s2 = 0
s = 0
for e in l:
s += e
s2 += e * e
return (s, s2)
и использовать результат в своей функции sigma
.
Edit: теперь вы можете вычислить дисперсию так: (s2 - (s*s) / N) / N
Принимая во внимание комментарий @Adam Bowen,
, имейте в виду, что если мы используем математические уловки и преобразуем исходные формулы
мы можем ухудшить результаты.
У вас есть два решения
Составьте список из своего итератора и повторяйте его столько раз, сколько хотите. Недостатком является то, что все будет в памяти, поэтому не подходит, если ваш файл большой. Простое использование itertools.tee также не спасет вас
Нет другого решения, кроме , вам не нужно передавать вывод get_mean в get_sigma, потому что в этом случае они могут быть только последовательно , но если вы удалите это ограничение, вы можете запускать обе функции параллельно, используя потоки, и использовать itertools.tee, чтобы иметь два итератора из одного
Из верхней части моей головы, я бы подкласс его и перезаписать метод put, чтобы обеспечить это. Если это перейдет через бросить исключение или сделать все, что кажется уместным.
Что-то вроде:
public class LimitedPBQ extends PriorityBlockingQueue {
private int maxItems;
public LimitedPBQ(int maxItems){
this.maxItems = maxItems;
}
@Override
public boolean offer(Object e) {
boolean success = super.offer(e);
if(!success){
return false;
} else if (this.size()>maxItems){
// Need to drop last item in queue
// The array is not guaranteed to be in order,
// so you should sort it to be sure, even though Sun's Java 6
// version will return it in order
this.remove(this.toArray()[this.size()-1]);
}
return true;
}
}
Edit: Both add and put invoke offer, поэтому переопределения должно быть достаточно
Edit 2: Should now remove the last element if over maxItems. Возможно, есть более элегантный способ сделать это.
-121--2348266-Я не уверен, что лучше всего сделать это на стороне клиента. Я бы рассмотрел возможность отправки абзацев обратно на сервер для выполнения работы. Но работа должна быть одинаковой в любом случае.
Прежде всего, возьмите все содержимое абзаца и убедитесь, что все это может быть в нескольких узлах в DOM. ( Read This ) Тогда потребуется создать синтаксический анализатор, который будет искать разделенные символы, игнорируя их, пока они находятся в объектах HTML.
В качестве примера. в атрибуте href следует игнорировать и не разделять. Во время синтаксического анализа можно сохранить число слов, а также разбить работу над местами. Сделайте каждое предложение объектом, содержащим все предложение и число слов. Таким образом, эти объекты можно переместить в массив, представляющий абзац. После этого можно выполнить итерацию в массиве и обернуть любое предложение в диапазон для выделения с помощью CSS, если число слов достигает порогового значения.
Основной проблемой являются Тэги, которая может быть частью двух предложений, таких как следующее.
I'm typing <b> in bold. NOW!</b>
То, о чем я говорил, не связано с этим, но вы можете сделать синтаксический анализатор более сложным позже, чтобы поддержать это.
Итак, краткий обзор моего разбора rambling через все символы с конечным автоматом, который имеет дело с подсчетом слов и расщеплением в правильном месте. При разделении добавьте собранные данные в массив. По завершении итерации через массив, выводящий вновь упакованные предложения.
-121--4501428-Я думаю, что Ник D имеет правильный ответ.
Предполагается, что вы хотите вычислить среднее значение и дисперсию в одном сдвиге файла (и вы на самом деле не хотите две функции, которые должны вызываться одна за другой), вы можете собрать сумму значений и их квадратов, и они используют такие суммы (вместе с количеством считываемых элементов), чтобы вычислить одновременно среднее и дисперсию.
Есть некоторые проблемы с числовой стабильностью, но идея в
http://en.wikipedia.org/wiki/Computational_formula_for_the_variance
является основным ингредиентом, который вам нужен. Некоторые дополнительные детали находятся на
http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
, где я предлагаю вам прочитать «Наивный алгоритм».
Надеюсь, что это поможет,
Массимо
Составьте список из итерируемого объекта или используйте itertools.tee ()
.
Поскольку я чувствую, что в нескольких ответах есть хорошие элементы, я хотел бы подвести итог:
Если ваш файл слишком большой, чтобы удобно поместиться в памяти, и если вы хотите получить хорошую точность дисперсии, вам нужно прочитать файл дважды (при одном проходе дисперсия будет разницей между двумя большими числами, что не является точным из-за ограничений плавающей точки). Обратите внимание, что ваша операционная система, скорее всего, обеспечит некоторое автоматическое ускорение при втором чтении файла, поскольку он может все еще находиться в оперативной памяти во время второго прохода.
Если вам не важна точность дисперсии, вы можете просто просмотреть файл один раз и вычислить величины, предложенные Nick D, с подробностями, приведенными в комментарии Адама Боуэна.
Я не уверен, что есть большой выбор.
В любом случае вам придется повторять числа дважды, поскольку стандартное отклонение потребует средней информации по каждому значению.
Если у вас достаточно памяти, вы можете получить доступ к вводу-выводу, загрузив файл в память во время первой итерации, но это все, IMO.