WedX - журнал о программировании и компьютерных науках

Применение двух уравнений к одному массиву

Я новичок в Python и Numpy, и я потратил много времени (дней) на поиск ответов на свой вопрос, но я запутался. У меня есть массив магнитуд для землетрясений, и мне нужно преобразовать их в другую форму магнитуды (Mb в Mo). Для величин меньше 4,3 мне нужно применить одно преобразование, а для величин больше или равных мне нужно применить второе преобразование. Мне нужно, чтобы выходные данные были в том же порядке, что и входные, и здесь я упираюсь в стену. Я могу получить преобразования для вывода в два отдельных массива, но я не могу понять, как написать программу, которая выбирает одно уравнение на основе величины, применяет его и переходит к следующей величине в массиве. Несмотря на то, что следующий пример явно неверен на многих уровнях, я думаю, он показывает, чего я пытаюсь достичь:

data = numpy.genfromtxt('OK_mag3.csv')

mag = numpy.asarray(data)

for x in mag:

    if x < 4.3:
        mw = 1.03 + 0.67 * x     
    else:
        mw = 0.1 + 0.88 * x

Кроме того, пример получения половины этого правильного:

mw = mag[mag<4.3]*0.67+1.03

но тогда я не знаю, как включить второе уравнение.

Любая помощь приветствуется!

10.07.2014

Ответы:


1
mw = numpy.where(mag < 4.3, 1.03 + 0.67 * mag, 0.1 + 0.88 * mag)

См. документы на странице numpy.where. Первый параметр преобразует data в логический список, вторые два параметра будут вычислять весь вектор с той или иной функцией; затем where выбирает, какой из двух результатов лучше на основе логического значения.

РЕДАКТИРОВАТЬ: Основываясь на проблемах, поднятых в комментариях, следующее не удваивает работу и позволяет избежать случаев, когда одно из вычислений будет недействительным, но по-прежнему занимает немного памяти для массива селекторов.

mw = numpy.zeros(len(mag))
select = mag < 4.3
mw[select] = 1.03 + 0.67 * mag[select]
select = ~select
mw[select] = 0.1 + 0.88 * mag[select]
10.07.2014
  • Гораздо лучше, чем мой ответ, с одной оговоркой: если mag очень велико или фактическое вычисление сложнее, чем OP, то промежуточные массивы могут занимать много памяти. Сомневаюсь, что это произойдет на практике, но стоит отметить. 10.07.2014
  • @sapi: Если вычисления сложны, да, потому что работа удваивается. Большой размер массивов не имеет большого значения: я использую три дополнительных массива, но и вы тоже (по крайней мере, если вы не использовали дополнительные numpy.wheres: mw < 4.3, снова mw < 4.3, mw[mw < 4.3]). Одного из них можно избежать, если запомнить mw < 4.3. Тем не менее, в наши дни увеличение памяти на 25% не так уж и важно. 10.07.2014
  • Что делает np.where, так это вычисляет оба уравнения для полного массива, а затем выбирает одно или другое для вывода на основе первого логического условия. Это делает использование np.where не очень хорошим вариантом, например. при проверке на 0, чтобы избежать ошибок деления на ноль... 10.07.2014
  • @ Амадан - Да, согласен. Просто решил, что это стоит отметить. 10.07.2014
  • Вместо select = select == False вы можете просто использовать ~select, например mw[~select] = 0.1 + 0.88 * mag[~select]. 10.07.2014
  • Первое решение, которое вы перечислили, сработало блестяще! У меня было ощущение, что это не должно быть слишком сложно, но ничего из того, что я нашел, не казалось применимым к моей проблеме. Спасибо большое за вашу помощь. (Я также поиграю с вашим предложением в редактировании, просто чтобы получить больше практики.) 10.07.2014

  • 2

    Вы можете добиться этого, используя np.where:

    In [1]: import numpy as np
    
    In [2]: arr = np.eye(3)
    
    In [3]: arr
    Out[3]:
    array([[ 1.,  0.,  0.],
           [ 0.,  1.,  0.],
           [ 0.,  0.,  1.]])
    
    In [4]: arr[np.where(arr==0)] += 2
    
    In [5]: arr
    Out[5]:
    array([[ 1.,  2.,  2.],
           [ 2.,  1.,  2.],
           [ 2.,  2.,  1.]])
    

    В вашем случае для каждого условия вы можете сделать что-то вроде:

    mw[np.where(mw < 4.3)] = mw[np.where(mw < 4.3)]*0.67 + 1.03
    
    10.07.2014
  • Я не был против, но хотел уточнить. Я думаю, что смысл вашего ответа в том, что вы использовали бы предложение where два раза подряд. Для конкретных перечисленных уравнений это решение работает (если вы сначала запустите *.67 + 1.03). Но в целом у вас могут возникнуть проблемы, верно? Например, если бы уравнение было *.67 + 5, для значения, которое изначально было 4,2, вы могли бы в конечном итоге выполнить второе уравнение. Напротив, ответ Амадана, кажется, обрабатывает этот пограничный случай. Вот почему я бы вместо этого согласился с его / ее ответом. 10.07.2014
  • Все использования where в этом ответе не нужны. 10.07.2014
  • @BehramMistree - Ну, определенно. Я предполагал, что вы предварительно рассчитаете индексы и будете работать оттуда. Однако ответ Амадана в этом отношении намного лучше. 10.07.2014
  • Я не имею ничего общего с понижением голосов, но понятнее и быстрее использовать логический массив для индексации без вызова np.where для преобразования их в индексы, то есть: mw[mw < 4.3] = mw[mw < 4.3]*0.67 + 1.03. Конечно, вы, вероятно, захотите сохранить логический массив раньше, например, mask = mw < 4.3; mw[mask] = mw[mask]*0.67 + 1.03, чтобы избежать дублирования операций. 10.07.2014
  • Как свидетельство того, насколько я новичок... Мне было интересно, как использовать np.‹что угодно› вместо numpy.‹что угодно›. Поэтому, несмотря на то, что другой ответ был проще для моей проблемы, я все же нашел этот отзыв действительно полезным! :-) 10.07.2014
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]