Файл: Учебное пособие С. К. Буйначев н. Ю. Боклаг.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 10.01.2024

Просмотров: 734

Скачиваний: 16

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

50
21.2. Создание массива
Для создания массива можно использовать функцию array(), в которой указано содержимое массива (в виде вложенных списков) и типа. Функция array() делает копию, если ее аргумент – массив.
Функция asarray() работает аналогично, но не создает нового масси- ва, когда ее аргумент уже является массивом:
>>> from Numeric import *
>>> print array([[1, 2], [3, 4], [5, 6]])
[[1 2]
[3 4]
[5 6]]
>>> print array([[l, 2, 3], [4, 5, 6]], Float)
[[ 1. 2. 3.]
[ 4. 5. 6.]]
>>> print array([78, 85, 77, 69, 82, 73, 67], 'с')
[NUMERIC]
В качестве элементов массива можно использовать следующие типы: Int8-Int32, UnsignedInt8-UnsignedInt32, Float8-Float64, Com- plex8-Complex64 и PyObject. Числа 8, 16, 32 и 64 показывают количе- ство битов для хранения величины. Типы Int, Unsignedlnteger, Float и
Complex соответствуют наибольшим принятым на данной платформе значениям. В массиве можно также хранить ссылки на произвольные объекты.
Количество размерностей и длина массива по каждой оси назы- ваются формой массива (shape). Доступ к форме массива реализуется через атрибут shape:
>>> from Numeric import *
>>> a = array(range(15), Int)
>>> print a.shape(15,)
>>> print a
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
>>> a.shape = (3, 5)
>>> print a.shape
(3, 5)
>>> print a

51
[[01234]
[56789]
[10 11 12 13 14]]
21.3. Методы массивов
Придать нужную форму массиву можно функцией Numeric, reshape(). Эта функция сразу создает объект-массив нужной формы из последовательности.
>>> import Numeric
>>> print Numeric.reshape("абракадабр", (5, -1))
[[а б]
[р а]
[к а]
[д а]
[б р]]
В этом примере цифра -1 в указании формы массива говорит о том, что соответствующее значение можно вычислить. Общее ко- личество элементов массива известно (десять), поэтому длину вдоль одной из размерностей задавать не обязательно. Через атрибут flat можно получить одномерное представление массива:
>>>а =аrrау([[1, 2], [3, 4]])
>>> b = a.flat
>>> b array([1, 2, 3, 4])
>>> b[0] = 9
>>> b array([9, 2, 3, 4])
>>> a array([[9, 2], [3, 4]])
Следует заметить, что это новый вид того же массива, поэтому присваивание значений его элементам приводит к изменениям в ис- ходном массиве. Функция Numeric.resize() похожа на Numer- ic.reshape(), но может подстраивать число элементов:

52
>>> print Numeric.resize("NUMERIC", (3, 2))
[[N U]
[M E]
[R 111
>>> print Numeric.resize("NUMERIC", (3, 4))
[[N U M E]
[R I C N]
[U M E R]]
Функция Numeric.zeros() порождает массив из одних нулей, а Numeric.ones() – из одних единиц. Единичную матрицу можно по- лучить с помощью функции Numeric. identity(n):
>>> print Numeric.zeros((2,3))
[[0 0 0]
[0 0 0]]
>>> print Numeric.ones((2,3))
[[1 1 1]
[1 1 1]]
>>>print Numeric.identity(4)
[[1 000]
[0100]
[0010]
[000 1]]
Для копирования массивов можно использовать метод copy():
>>> import Numeric
>>> а = Numeric.arrayrange(9)
>>> a.shape = (3, 3)
>>> print a
[[0 1 2]
[3 4 5]
[6 7 8]]
>>> a1 = a.copy()
>>> a1[0, 1] = -1 #операция над копией
>>> print a
[[0 1 2]


53
[3 4 5]
[6 7 8]]
Массив превращается обратно в список методом tolist():
>>> а.tolist()
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
21.4. Срезы массивов
Объекты-массивы Numeric используют расширенный синтаксис выделения среза. Следующие примеры иллюстрируют различные ва- рианты записи срезов. Функция Numeric.arrayrange() является ана- логом range() для массивов.
>>> import Numeric
>>> а = Numeric.arrayrange(24) + 1
>>> a.shape = (4, 6)
>>> print a #исходный массив
[[123456]
[7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
>>> print a[1,2] # элемент
1,2 9
>>> print a[l,:] # строка 1
[7 8 9 10 11 12]
>>> print a[l]
# тоже строка 1
[7 8 9 10 11 12]
>>> print a[:,l] # столбец 1
[ 2 8 14 20]
>>> print a[-2,:] #предпоследняя строка
[13 14 15 16 17 18]
>>> print a[0:2,1:3] #окно 2х2
[[2 3]
[8 9]]
>>> print a[l,::3] #каждый третий элемент строки 1
[7 10]
>>> print a[:,::-!]#элементы строк в обратном порядке

54
[[6 5 4 3 2 1]
[12 11 10 9 8 7]
[18 17 16 15 14 13]
[24 23 22 21 20 19]]
Срез не копирует массив (как это имеет место со списками), а дает доступ к некоторой части массива. Далее в примере меняется на 0 каждый третий элемент строки 1:
>>>а[1,::3]=Numeric.array([0,0])
>>> print a
[[1 2 3 4 5 6]
[0 8 9 0 11 121
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
В следующих примерах находит применение достаточно редкая синтаксическая конструкция: срез с многоточием (Ellipsis). Многото- чие ставится для указания произвольного числа пропущенных раз- мерностей (:, :, ..., : ):
>>> import Numeric
>>> а = Numeric.arrayrange(24) + 1
>>> а.shape = (2,2,2,3)
>>> print a
[[[[ 1 2 3]
[4 5 6]]
[[7 8 9]
[10 11 12]]]
[[[13 14 15]
[16 17 18]]
[[19 20 21]
[22 23 24]]]]
>>>print a[0, ...] # 0-й блок
[[[ 1 2 3]
[4 5 6]]
[[7 8 9]
[10 11 12]]]

55
>>>print a[0, :, :,0] #по перв.и послед.размерности
[[1 4]
[ 7 10]]
>>> print a[0, ...,0]
#то же,с использ.многоточия
[[ 1 4]
[ 7 10]]
21.5. Универсальные функции элементов массивов
Модуль Numeric определяет набор функций для применения к элементам массива. Функции применимы не только к массивам, но и к последовательностям (к сожалению, итераторы пока не поддер- живаются). В результате получаются массивы.
Функция
Описание
1 2 add(x,у)
Сложение subtract(х, у)
Вычитание multiply(х, у)
Умножение divide(х, у)
Деление remainder(x,у),fmod(x,у)
Получение остатка от деления
(для целых чисел и чисел с плава- ющей запятой) power(х)
Возведение в степень sqrt(x)
Извлечение корня квадратного negative(x), absolute(x), fabs(x)
Смена знака и абсолютное значе- ние ceil(x), floor(x)
Наименьшее (наибольшее) целое, большее (меньшее) или равное ар- гументу hypot(x,у)
Длина гипотенузы по двум кате- там: x,y sin(x), cos(x), tan(x)
Тригонометрические функции arcsin(x), arccos(x), arctan(x) Обратные тригонометрические функции


56
Окончание таблицы
1 2 arctan2(x,у)
Арктангенс от частного аргумента sinh(x), cosh(x), tanh(x)
Гиперболические функции arcsinh(x), arccosh(x), arctanh(x)
Обратные гиперболические функ- ции ехр(х)
Экспонента log(x) , logl0(x)
Натуральный и десятичный лога- рифмы maximum (х, у)
Максимум minimum(x,у)
Минимум conjugate (x)
Сопряжение (для комплексных чисел) equal(х, у), not_equal(x,у)
Равно, не равно greater(х, у), greater_equal(x, у)
Больше, больше или равно less(x,у), less_equal(х, у)
Меньше, меньше или равно logical_and(x, у),
logical_or(x,у)
Логические И, ИЛИ logical_xor(x,у)
Логическое исключающее ИЛИ logical_not(х)
Логическое НЕ bitwise_and(x, у),
bitwise_or(x,у)
Побитовые И, ИЛИ bitwise_xor(x,у)
Побитовое исключающее ИЛИ invert(x)
Побитовая инверсия left_shift(х, n), right_shift(x, n) Побитовые сдвиги влево и вправо на n битов
21.6. Функции модуля Numeric
В таблице представлены функции модуля Numeric, которые яв- ляются краткой записью некоторых наиболее употребительных соче- таний функций и методов. Параметр axis в функциях указывает раз- мерность.

57
Функция
Аналог функции sum(a, axis) add.reduce(a, axis) cumsum(a, axis) add.accumulate(a, axis) product(a, axis) multiply.reduce(a, axis) cumproduct(a, axis) multiply.accumulate(a, axis) alltrue(a, axis) logical_and.reduce(a, axis) sometrue(a, axis) logical_or.reduce(a, axis)
21.7. Модуль LinearAlgebra
Модуль LinearAlgebra содержит алгоритмы линейной алгебры, в частности нахождение определителя матрицы, решений системы линейных уравнений, обращения матрицы, нахождения собственных чисел и собственных векторов матрицы, разложения матрицы на множители.
Функция LinearAlgebra.determinant() находит определитель матрицы:
>>> import Numeric, LinearAlgebra
>>> print LinearAlgebra.determinant( Numeric.array([[1,-2],[1,5]]))
7
Функция LinearAlgebra.solve_linear_equations()решает ли- нейные уравнения вида ах=b по заданным аргументам а и b:
>>> import Numeric, LinearAlgebra
>>> а = Numeric.array([[1.0,2.0],[0.0,1.0]])
>>> b = Numeric.array([1.2,1.5])
>>> х = LinearAlgebra.solve_linear_equations(a,b)
>>> print "x=", x x = [-1.8 1.5]
Когда матрица а имеет нулевой определитель, система имеет не единственное решение и возбуждается исключение LinAlgError:

58
>>> а=Numeric.array([[1.0,2.0],[0.5,1.0]])
>>> x=LinearAlgebra.solve_linear_equations(a,b)
Traceback(most recent call last):
File "", line 1, in ?
File "/usr/local/lib/python2.3/site- packages/Numeric/LinearAlgebra.py", line 98, in solve_linear_equations raise LinAlgError, 'Singular matrix' LinearAlgebra.LinAlgError: Singu- lar matrix
Функция LinearAlgebra.inverse() находит обратную матрицу.
Однако не следует решать линейные уравнения умножением Lin- earAlgebra.inverse() на обратную матрицу, так как она определена через LinearAlgebra.solve_linear_equations(): solve_linear_equations(a,Numeric.identity(a.shape[0]))
Функция LinearAlgebra.eigenvalues()находит собственные значения матрицы, а LinearAlgebra.eigenvectors() – собственные значения и собственные векторы.
>>>from Numeric import array, dot
>>>from LinearAlgebra import *
>>> a=array([[-5,2],[2,-7]])
>>> lmd = eigenvalues(a)
>>> print "Собственные значения:",lmd
Собственные значения: [-3.76393202 -8.23606798]
>>> (lmd, v) = eigenvectors(a)
>>> print "Собственные вектора:"
Собственные вектора:
>>> print v
[[ 0.85065081 0.52573111]
[-0.52573111 0.85065081]]
>>> print "Проверка:", dot(a,v[0]) – v[0] * lmd[0]
Проверка: [ -4.44089210e-16 2.22044605e-16]
Проверка показывает, что тождество выполняется с достаточно большой точностью (числа совсем маленькие, практически нули): собственные числа и векторы найдены верно.


59
21.8. Модуль RandomArray
В модуле собраны функции для генерации массивов случайных чисел различных распределений и свойств. Их можно применять для математического моделирования стохастических систем.
Функция RandomArray.random() создает массивы из псевдо- случайных чисел, равномерно распределенных в интервале (0,1):
>>>import RandomArray
>>>print RandomArray.random(10)
#10 псевдослучайных чисел
[0.28374212 0.19260929 0.07045474 0.305476820.10842083 0.14049676 0.01347435 0.37043894 0.47362471 0.37673479]
>>> print RandomArray.random([3,3])
# массив 3х3 из псевдослучайных чисел
[[ 0.53493741 0.44636754 0.20466961]
[ 0.8911635 0.03570878 0.00965272]
[ 0.78490953 0.20674807 0.23657821]]
Функция RandomArray.randint() для получения массива равно- мерно распределенных чисел из заданного интервала и заданной формы:
>>> pront RandomArray.randint(1,10,[10])
[8 1 9 9 7 5 2 5 3 2]
>>> print RandomArray.randint(1,10,[10])
[2 2 5 5 7 7 3 4 3 7]
Можно получать и случайные перестановки с помощью
RandomArray.permutation():
>>> print RandomArray.permutation(6)
[4 0 1 3 2 5]
>>> print RandomArray.permutation(6)
[1 2 0 3 5 4]
Доступны и другие распределения для получения массива нор- мально распределенных величин с заданным средним и стандартным отклонением:

60
>>> print RandomArray.normal(0,1,30)
[-1.0944078 1.24862444 0.20415567 -0.74283403 0.72461408 -
0.57834256 0.30957144 0.8682853 1.10942173 -0.39661118 1.33383882 1.54818618 0.18814971 0.89728773 -0.86146659 0.0184834 -1.46222591 -0.78427434 1.09295738 -1.09731364 1.34913492 -0.75001568 -0.11239344 2.73692131 -0.19881676 -
0.49245331 1.54091263 -1.81212211 0.46522358 -0.08338884]
Следующая таблица приводит функции для других распределе- ний.
Функция и ее аргументы
Описание
1 2
F(dfn,dfd,shape=[])
F-распределение beta(а,b,shape=[])
Бета-распределение binomial(trials,p,shape=[])
Биномиальное распределение chi_square(df,shape=[])
Распределение хи-квадрат exponential(mean, shape=[])
Экспоненциальное распреде- ление gamma(a,r,shape=[])
Гамма-распределение multivari- ate_normal(mean,cov,shape=[])
Многомерное нормальное распределение negative_binomial(trials,p, shape=[])
Негативное биномиальное noncentral_F(dfn,dfd,nconc, shape=[])
Нецентральное
F-распределение noncentral_chi_square(df, nconc, shape=[])
Нецентральное хи-квадрат распреде-ление normal(mean,std,shape=[])
Нормальное распределение permutation(n)
Случайная перестановка poisson(mean,shape=[])
Пуассоновское распределение randint(min,max=None,shape=[]) Случайное целое

61
Окончание таблицы
1 2 random(shape=[])
Равномерное распределение на интервале (0, 1) random_integers(max,min=l, shape=[])
Случайное целое standard_normal(shape=[])
Стандартное нормальное рас- пределение uniform(min,max,shape=[])
Равномерное распределение
22. ОБРАБОТКА ТЕКСТОВ. РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ.
UNICODE
Подобработкой текстовпонимается анализ, преобразование, поиск, порождение текстовой информации. Обработка естественных текстов – это процесс неискусственного интеллекта. Здесь не рас- сматривается обработка текстов посредством текстовых процессоров и редакторов, хотя некоторые из них (например, Cooledit) предостав- ляют возможность писать макрокоманды на Python.
Для Python созданы модули для работы с естественными языка- ми, для лингвистических исследований. Хорошим примером служит nltk (the Natural Language Toolkit).
22.1. Строки
Строки в языке Python являются типом данных, специально предназначенным для обработки текстовой информации. Строка мо- жет содержать произвольно длинный текст (ограниченный имеющей- ся памятью).
В новых версиях Python имеются два типа строк: обычные стро- ки (последовательность байтов) и Unicode-строки (последователь- ность символов). В Unicode-строке каждый символ может занимать в памяти 2 или 4 байта в зависимости от настроек периода компиляции.
Четырехбайтовые знаки используются в основном для восточных языков.
В языке Python и стандартной библиотеке за некоторыми ис- ключениями строки и Unicode-строки взаимозаменяемы, в собствен- ных приложениях для совместимости с обоими видами строк следует


62 избегать проверок на тип. Если это необходимо, можно проверять принадлежность базовому (для строк и Unicode-строк) типу с помо- щью isinstance(s,basestring).
При использовании Unicode-строк следует помнить, что именно
Unicode-представление является главным, а все остальные кодировки
– лишь частными случаями представления текста, которые не могут передать всех символов. Без такой установки будет непонятно, поче- му преобразование из восьмибитной кодировки называется decode
(декодирование). Для внешнего представления можно с успехом ис- пользовать кодировку UTF-8, хотя, конечно, это зависит от решаемых задач.
Для того чтобы Unicode–литералы в Python-программе воспри- нимались интерпретатором правильно, необходимо указать кодиров- ку в начале программы, записав в первой или второй строке, напри- мер, следующее (для Unix/Linux):
# -*- coding: koi8-r -*- или (под Windows):
# -*- coding: cpl251 -*-
Могут быть и другие варианты:
# -*- coding: latin-1 -*-
# -*- coding: utf-8 -*-
# -*- coding: mac-cyrillic -*-
# -*- coding: iso-5 -*-
Полный перечень кодировок (и их псевдонимов):
>>> import encodings.aliases
>>> print encodings.aliases.aliases
{'iso_ir_6': 'ascii',
'maccyrillic': 'mac_cyrillic',
'iso_celtic': 'iso8859_14',
'ebcdic_cp_wt': 'cp037',
'ibm500': 'cp500', ...
Если кодировка не указана, то считается, что используется us- ascii. При этом интерпретатор Python будет выдавать предупрежде- ния при запуске модуля:

63 sys:1: DeprecationWarning: Non-ASCII character '\xf0' in file exam- ple.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
22.2. Строковые литералы
Строки можно задать в программе с помощьюстроковых лите- ралов.Литералы записываются с использованием апострофов «'», ка- вычек «"» или этих же символов, взятых трижды. Внутри литералов обратная косая черта имеет специальное значение. Она служит для ввода специальных символов и для указания символов через коды.
Если перед строковым литералом поставлено r, то обратная косая черта не имеет специального значения (r – от английского слова raw, строка задается как есть). Unicode-литералы задаются с префиксом s.
Вот несколько примеров: s1 = "строка 1" s2 = r'\1\2' s3 = """apple\ntree""" # \n- символ перевода строки
Обратная косая черта не должна быть последним символом в литерале, то есть str\ вызовет синтаксическую ошибку.
Указание кодировки позволяет применять в Unicode-литералах приведенную в начале программы кодировку. Если кодировка не ука- зана, можно пользоваться только кодами символов, заданными через обратную косую черту.
22.3. Операции над строками
К операциям над строками, которые имеют специальную син- таксическую поддержку в языке, относятся, в частности, конкатена- ция (склеивание) строк, повторение строки, форматирование:
>>> print"А" +"В","А"*5,"%s" %"А"
АВ ААААА А
В операции форматирования левый операнд является строкой формата, а правый может быть либо кортежем, либо словарем, либо некоторым значением другого типа: