Нахождение частоты диапазона чисел в Mathematica

#wolfram-mathematica

#wolfram-mathematica

Вопрос:

Учитывая список чисел в Mathematica, как бы мне извлечь из этого списка общее количество чисел между числами a и b , которые я указываю?

Ответ №1:

Самый прямой способ — это просто:

 Count[data, x_ /; a <= x <= b]
  

Однако существуют гораздо более быстрые способы обработки большинства данных, и на этот раз благодаря Карлу Воллу:

 Tr@Unitize@Clip[data, {a, b}, {0, 0}]
  

Метод Карла Волла особенно быстр, но, как отметил Йода, он терпит неудачу, если ваш список содержит нули, а ваш диапазон также превышает ноль. Вот еще один метод от Кевина Дж. Макканна, который обрабатывает этот случай и по-прежнему очень быстр:

 Tr@UnitStep[(data - a)*(b - data)]
  

Как чистая функция [данные, a, b]:

 Tr@UnitStep[(#-#2)*(#3-#)]amp;
  

Комментарии:

1. Волшебник: А, так вот с чем тебе нужно что-то сделать Count . Я попытался придать ему шаблон типа for Cases , но это ни к чему не обязывало.

2. Мастер: Второй подход не будет работать, когда 0 находится в вашем диапазоне.

Ответ №2:

Вот один из подходов, который вы можете попробовать:

 freq[a_, b_, list_] := Total@Boole@Cases[list, x_ :> a <= x <= b]
lst = RandomInteger[10, 20]
Out = {6, 1, 1, 6, 3, 1, 10, 0, 2, 10, 3, 5, 9, 1, 5, 5, 3, 8, 2, 3}

freq[3, 6, lst]
Out = 9
  

Альтернативный подход, использующий IntervalMemberQ , заключается в

 freq[a_, b_, list_] :=
 Total@Boole@IntervalMemberQ[Interval[{a, b}], list]
  

Ответ №3:

другой подход заключается в

 NumberOfNumbers[lst_?ListQ, lwr_?NumberQ, upr_?NumberQ] := 
 Length@Select[lst, (lwr <= # <= upr) amp;]
  

D

Ответ №4:

Пожалуйста, загляните в BinCount :

 In[176]:= BinCounts[Range[30], {{2, 11/2}}]

Out[176]= {4}
  

Сравнить с прямым подсчетом:

 In[177]:= Count[Range[30], x_ /; 2 <= x < 11/2]

Out[177]= 4
  

Комментарии:

1. Саша, в Mathematica 7 BinCounts выполняется очень медленно. Было ли это улучшено в последнее время?

2. Время в списке из 5 миллионов реалов: Count = 3,234 секунды; BinCounts = 39,344 секунды; Clip = 0,078 секунды

3. @Mr.Wizard BinCounts улучшен в версии 8, но по-прежнему проигрывает Count в 2 раза по времени.

4. Я перекодировал BinCounts и DigitCount , чтобы быть быстрее. Меня удивило, что они не были оптимизированы лучше. Я рад слышать, что этот вопрос был решен сейчас. Кроме того, простите меня за то, что я не поддержал этот ответ, но на данный момент я не вижу в BinCounts этом преимущества.