Сегодня я бы хотел продолжить рассказ про замечательную библиотеку для работы с числовыми массивами в php numphp. Ранее я уже делал краткий обзор на неё тут. С тех пор библиотека обросла функционалом, и, что самое главное, научилась работать с многомерными массивами или матрицами. Про них, в основном и будет идти речь.
Без лишних вступлений сразу пример того, как можно создать матрицу 3 на 4, используя возможности numphp.
В результате мы получаем объект np_array. Более того, каждая строка матрицы является также объектом этого типа. Это позволяет делать универсальные выборки.
К примеру, для доступа ко второй строке можно использовать стандартную логику
Но, это было бы неинтересно =)
Благодаря тому, что любой срез матрицы является np_array, мы можем одним махом узнать, к примеру, среднее значение для всей третьей строки
Более того, используя операторы сравнения, можно выбрать все элементы матрицы, удовлетворяющие условию, к примеру больше 5
И получить их сумму
Как я упомянул выше, мы можем использовать всю мощь срезов, реализованных в numphp, применимо к матрицам тоже. К примеру, взять вторую и третью строку
Более детальное описание возможностей можно найти в документации библиотеки.
На данный момент к матрицам можно применять теже операции, что и к векторным массивам. Операция будет применяться к каждому элементу исходной матрицы.
Можно так же суммировать матрицу и вектор. В таком случае вектор будет суммироваться с каждой строкой матрицы
Или даже суммировать две матрицы. Тут так же будет виден один из способов как можно сгенерировать матрицу нужного размера.
Таким образом можно значительно упростить и ускорить работу с матрицами и векторами.
Каждый объект np_array может легко менять свою форму. Под формой я подразумеваю размерность конкретного объекта. К примеру
Упрощенно можно считать, что первое число означает количество строк, второе — количество колонок. Но, важно понимать, что библиотека позволяет работать с n-мерными массивами.
Если мы хотим взять нашу матрицу из примера и сделать из неё, скажем, массив точек на координатной доске, мы можем превратить её в матрицу размерности 6х2
Если нужно представить n-мерный массив как 1-мерный, можно воспользоваться методом flatten
Данный подход удобен для быстрой генерации какого-то тестового набора данных нужной формы.
Последнее что хотел бы описать тут, но далеко не последнее что умеет библиотека — работа с диагональными срезами матриц.
Практически аналогичным способом можно сгенерировать матрицу, с заданной диагональю
На самом деле библиотека включает в себя ещё много приятных и полезных вещей для работы с числовыми массивами и матрицами любой размерности. Комбинируя их, можно очень быстро и просто делать вычисления, основанные на данных. В планах ещё много чего хотелось бы реализовать, поэтому работа над библиотекой продолжается.
Дополнительные возможности и документацию вы можете найти здесь.
Также, если вы хотите внести свой вклад в развитие — буду рад обсудить любые вопросы.
Без лишних вступлений сразу пример того, как можно создать матрицу 3 на 4, используя возможности numphp.
$matrix = new np_array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]); // matrix [[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]
В результате мы получаем объект np_array. Более того, каждая строка матрицы является также объектом этого типа. Это позволяет делать универсальные выборки.
К примеру, для доступа ко второй строке можно использовать стандартную логику
$row = $matrix[1]; //row [4, 5, 6, 7]
Но, это было бы неинтересно =)
Благодаря тому, что любой срез матрицы является np_array, мы можем одним махом узнать, к примеру, среднее значение для всей третьей строки
$avg = $matrix[2]->mean(); // avg 9.5
Более того, используя операторы сравнения, можно выбрать все элементы матрицы, удовлетворяющие условию, к примеру больше 5
$result = $matrix[$matrix->gt(5)] // or $result = $matrix[$matrix['> 5']] // result [ 6, 7, 8, 9, 10, 11]
И получить их сумму
$result = $matrix[$matrix['> 5']]->sum() // result 51
Как я упомянул выше, мы можем использовать всю мощь срезов, реализованных в numphp, применимо к матрицам тоже. К примеру, взять вторую и третью строку
$result = $matrix['1:3']; // result [[ 4, 5, 6, 7], [ 8, 9, 10, 11]]
Более детальное описание возможностей можно найти в документации библиотеки.
Математические операции
На данный момент к матрицам можно применять теже операции, что и к векторным массивам. Операция будет применяться к каждому элементу исходной матрицы.
$result = $matrix->mul(5); // multiply // result [[ 0, 5, 10, 15], [20, 25, 30, 35], [40, 45, 50, 55]]
Можно так же суммировать матрицу и вектор. В таком случае вектор будет суммироваться с каждой строкой матрицы
$result = $matrix->add([1, 2, 3, 4]); [[ 1, 3, 5, 7], [ 5, 7, 9, 11], [ 9, 11, 13, 15]]
Или даже суммировать две матрицы. Тут так же будет виден один из способов как можно сгенерировать матрицу нужного размера.
$diffMartrix = Generator::ones([3, 4]); // diffMartrix [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]] $result = $matrix->add($diffMatrix); // result [[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]]
Таким образом можно значительно упростить и ускорить работу с матрицами и векторами.
Изменение размеров
Каждый объект np_array может легко менять свою форму. Под формой я подразумеваю размерность конкретного объекта. К примеру
$list = new np_array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); $list->shape // [10] $matrix = new np_array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]); $matrix->shape // [3, 4]
Упрощенно можно считать, что первое число означает количество строк, второе — количество колонок. Но, важно понимать, что библиотека позволяет работать с n-мерными массивами.
Если мы хотим взять нашу матрицу из примера и сделать из неё, скажем, массив точек на координатной доске, мы можем превратить её в матрицу размерности 6х2
$newMatrix = $matrix->reshape([6, 2]); // newMatrix [[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9], [10, 11]]
Если нужно представить n-мерный массив как 1-мерный, можно воспользоваться методом flatten
$result = $matrix->flatten(); // result [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Данный подход удобен для быстрой генерации какого-то тестового набора данных нужной формы.
$result = Generator::arange(1, 15)->reshape([2, 7]); // result [[ 1, 2, 3, 4, 5, 6, 7], [ 8, 9, 10, 11, 12, 13, 14]]
Последнее что хотел бы описать тут, но далеко не последнее что умеет библиотека — работа с диагональными срезами матриц.
$matrix = Generator::arange(16)->reshape([4, 4]); // matrix [[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]] // get matrix diagonal $result = $matrix->diagonal(); //result [ 0, 5, 10, 15]
Практически аналогичным способом можно сгенерировать матрицу, с заданной диагональю
$matrix = Generator::diagonal([5, 3, 1]); // matrix [[5, 0, 0], [0, 3, 0], [0, 0, 1]]
На самом деле библиотека включает в себя ещё много приятных и полезных вещей для работы с числовыми массивами и матрицами любой размерности. Комбинируя их, можно очень быстро и просто делать вычисления, основанные на данных. В планах ещё много чего хотелось бы реализовать, поэтому работа над библиотекой продолжается.
Дополнительные возможности и документацию вы можете найти здесь.
Также, если вы хотите внести свой вклад в развитие — буду рад обсудить любые вопросы.
