Я играю с NumPy
и Scipy
и у меня возникли проблемы с поиском функции в документации. Поэтому я задавался вопросом, может ли кто-нибудь помочь.
Предположим, что у меня есть массив в NumPy
с двумя столбцами и k
строками. Одна колонка служит числовым индикатором (например, 2 = male
, 1 = female
, 0 = unknown
), а вторая колонка - это, пожалуй, list
значений или баллов.
Предположим, что я хочу найти стандартное отклонение (может быть среднее или другое, просто хочу применить функцию) значений для всех строк с индикатором 0, а затем для 1 и, наконец, 2.
Есть ли предопределенная функция для создания этого для меня?
В R
эквивалент можно найти в пакете plyr
. У NumPy
и/или Scipy
есть эквивалент, или я застрял в создании маски для этого массива, а затем каким-то образом фильтрую эту маску, а затем применил мою функцию?
Как всегда, спасибо за вашу помощь!
Если я понимаю ваше описание, у вас есть набор данных примерно так:
In [79]: x=np.random.randint(0,3,size=100)
In [80]: y=np.random.randint(0,100,size=100)
In [81]: d=np.vstack([x,y]).T
In [88]: print d[:5,:]
[[ 0 43]
[ 1 60]
[ 2 60]
[ 1 4]
[ 0 30]]
В этой ситуации numpy.unique
может использоваться для создания массива уникальных "ключевых" значений:
In [82]: idx=np.unique(d[:,0])
In [83]: print idx
[0 1 2]
и те значения, которые используются для генерации выражения генератора следующим образом:
[113]: g=(d[np.where(d[:,0]==val),1].std() for val in idx)
Генератор g
испускает стандартное отклонение всех записей в d
которые соответствуют каждой записи в индексе. numpy.fromiterator
можно затем использовать для сбора результатов:
In [114]: print np.vstack([idx,np.fromiter(g,dtype=np.float)]).T
[[ 0. 26.87376385]
[ 1. 29.41046084]
[ 2. 24.2477246 ]]
Обратите внимание, что на последнем этапе во время стекирования происходит переход ключей к плавающей запятой, вы можете не захотеть этого в зависимости от ваших данных, но я просто сделал это для иллюстративных целей, чтобы получить "хороший" внешний результат для публикации.
Для этого вы можете использовать операции маскированного массива. http://docs.scipy.org/doc/numpy/reference/maskedarray.html#maskedarray
Чтобы создать маску, вы можете использовать функцию numpy.where, например:
male_mask = numpy.where(a[:,0]==2, False, True)
female_mask = numpy.where(a[:,0]==1, False, True)
Затем не забудьте использовать специальные функции из numpy.ma: http://docs.scipy.org/doc/numpy/reference/routines.ma.html.
male_average = numpy.ma.average(ma.array(a[:,1], mask=male_mask))
EDIT: на самом деле это работает так же хорошо:
numpy.ma.average(ma.array(a[:,1], mask=a[:,0]!=value))