Part 3: Advanced calculations / より進んだ計算

Mappings / 写像(マッピング)

Mappings store associations between a set of keys and a set of values. They can be regarded as generalizations of sequences, because sequences are like mappings whose keys are a range of integers. Mappings allow more general keys, but define no order of their elements. There are other essential differences between sequences and mappings, so the two should be kept clearly separate.

写像は、値 (values) の組にキー (keys) の組を付随させて格納するもので、列の一般化とみなすことができます。なぜなら、列はある範囲の整数をキーとする写像のようなものだからです。 写像はより一般的なキーが使えますが、要素の並ぶ順番を指定することはできません。 列と写像の間には他にも基本的な相違があるので、両者ははっきりと区別されるべきです。

Mappings are accessed much like sequences: mapping[key] returns the value associated with the key, and mapping[key]=value changes it. A list of all keys is available with mapping.keys(), and a list of all values with mapping.values(). A list of (key, value) tuples can be obtained with mapping.items().

写像の扱いは列の場合とほぼ同様です:mapping[key] はそのキーに当てられた値を返しますし、値を変更するには mapping[key]=value とします。 全てのキーまたは値からなるリストは、それぞれ mapping.keys()mapping.values() で得られます。 キーと値のタプル (key, value) からなるリストは、mapping.items() により得られます。

Dictionaries / 辞書

The most frequently used mappings (and the only kind discussed in this course) are dictionaries. They allow any non-mutable object to be a key, i.e. any object that cannot change during its lifetime. This means that lists, dictionaries, and arrays cannot be used as keys, whereas integers, tuples, and strings (among many others) are allowed. Values can be arbitrary objects.

最も頻繁に使われる(そしてこのコースで議論する唯一の)写像は、辞書です。辞書のキーには不易のオブジェクト、すなわち変更不可能なオブジェクトであれば何でも許されます。 つまり、リスト、辞書、配列はキーとしては使えませんが、整数、タプル、文字列(他にも沢山あります)は許されます。 値には任意のオブジェクトが使えます。

The following example creates a dictionary containing the atomic masses of some chemical elements. It then adds another entry and finally calculates the mass of a water molecule.

次の例は、いくつかの元素の原子質量からなる辞書を生成した後、もう一つ項目を加え、最後に水分子の質量を計算します。

atomic_mass = {'H': 1., 'C': 12, 'S': 32}
atomic_mass['O'] = 16.
print atomic_mass['O'] + 2*atomic_mass['H']

A dictionary entry can be deleted with del dictionary[key].

辞書の項目は、del dictionary[key] によって削除できます。

Arrays / 配列

Arrays are another kind of sequence object, having special properties optimized for numerical applications. Arrays and functions dealing with them are defined in the module Numeric, which also contains the math functions introduced earlier. It is a good idea to begin an interactive session for numerical calculations by typing from Numeric import *.

列オブジェクトにはもう一種類、特に数値計算のために最適化された、配列というものがあります。配列と、配列を扱う関数は、Numeric モジュールで定義されています。 これは、既に導入した数学関数も含んでいます。数値計算用の対話型セッションを始める際に、まず from Numeric import * と入力するのは良い考えです。

Arrays have two properties that distinguish them from other sequences: they can be multidimensional, and their elements are all of the same type, either integers or real numbers or complex numbers. (There are also arrays of characters, single-precision real numbers, and general Python objects, but they will not be discussed in this course.) The number of dimensions is limited to fourty.

配列は、他の列と異なる二つの性質を持っています:多次元配列が使えること、および配列要素は整数、実数、複素数のいずれかで、全要素が同じ型であることです。 (文字、単精度実数、一般の Python オブジェクトの配列もあるのですが、このコースでは対象としません。) 次元数は40次元までという制限があります。

Arrays are created from other sequences by the function Numeric.array. Multidimensional arrays are created from nested sequences. An optional second argument indicates the type of the array (Integer, Float, or Complex). If the type is not indicated, it is inferred from the data.

配列は、他の列から Numeric.array 関数によって生成されます。 多次元配列は、入れ子になった列から作ります。 この関数には、二番目の引数によって配列の型を指定するオプションがあります(Integer, Float, Complex のいずれか)。 指定がなかった場合には、データの型から推定します。

The following example creates a one-dimensional array of integers and a three-dimensional array of real numbers:

次の例は、一次元の整数配列と三次元の実数配列を生成します:

from Numeric import *

integer_array = array([2, 3, 5, 7])
print integer_array.shape

real_array = array([ [ [0., 1.],
                       [2., 3.] ],
                     [ [4., 5.],
                       [6., 7.] ],
                     [ [8., 9.],
                       [10., 11.] ] ])
print real_array.shape
The shape of an array, which is printed in the example, is a tuple containing the lengths of the dimensions of the array, (4,) for the first array and (3, 2, 2) for the second one. The number of dimensions, i.e. the length of the shape, is called the rank of the array. The standard number objects (integers, real and complex numbers) can be regarded as arrays of rank zero.

例中で、配列の形状 (shape) が印字されていますが、これは配列の各次元の長さを表すタプルで、一番目の配列に対しては (4,)、二番目のついては (3, 2, 2) となります。 次元数、すなわち形状の長さは、配列の階数 (rank) と呼ばれるものです。 通常の数オブジェクト(整数、実数、複素数)は、階数ゼロの配列と見なすことができます。

There are a few functions in module Numeric which create special arrays. The function zeros(shape, type) returns an array of the specified shape (a tuple) with all elements set to zero. The second argument specifies the type (Integer, Float or Complex) and is optional; the default is Integer. The function ones(shape, type) works analoguously and sets the elements to one. The function arrayrange(first, last, step) works much like range, but returns an array (of rank one) and accepts real-number arguments in addition to integers.

Numeric モジュールには、特別な配列を生成する関数が2、3あります。 zeros(shape, type) 関数は、shape (というタプル)で指定された形状を持ち、全要素がゼロであるような配列を返します。

Arrays support an extended form of the indexing used for sequences. In addition to the forms a[i] (single element) and a[i:j] (subarray from i to j), there is the form a[i:j:k] that extracts a subarray from i to j with an increment of k. For multidimensional arrays, the indices/ranges are separated by commas. If there are fewer indices than dimensions, indices are assigned starting from the left. Indexed arrays can also be used as the target of an assignment, as for lists.

配列では、列の場合よりも拡張された添字付けが使えます。 a[i](単一要素)やa[i:j](i から j の部分列)に加えて、a[i:j:k] という形が使え、これは増分 k で i から j までの部分列を取り出します。 多次元配列では、添字および範囲はカンマで区切ります。次元数よりも少ない添字しか与えられなかった場合には、添字は左から割り当てられます。 添字付けた配列は、リストの場合と同様、代入先としても使えます。

Here are some examples of array indices:

配列添字の例を示します:

import Numeric

# Create a zero array
# ゼロ配列を生成
a = Numeric.zeros((4, 2, 3), Numeric.Float)

# Set a specific element to one
# 特定の要素に1を代入
a[2, 1, 0] = 1.

# Set all elements with first index 0 to 2.5
# 第一添字がゼロである全ての要素に 2.5 を代入
a[0] = 2.5

# Print all elements with first index 0 and last index 1
# 最初の添字がゼロ、最後の添字が1であるような全ての要素を印字
print a[0,:,1]

There are two special indices that do not directly select elements. The special index ... (three dots) "skips" dimensions such that indices following it are assigned starting from the right. For example, a[..., 0] selects all elements with 0 as their last index, and works for any number of dimensions. The special index NewAxis (defined in module Numeric) inserts a new dimension of length one. For example, if a has the shape (2, 2), then a[:, Numeric.NewAxis, :] has the shape (2, 1, 2) and the same elements as a.

直接的に要素を指定しない特別な添字が二種類あります。特殊添字 ...(点3つ)は、それに続く添字が右から割り付けられる様に、次元を "スキップ" します。 例えば、a[..., 0] は最後の添字がゼロであるような全要素を選び出します。これは任意の次元数に使えます。 特殊添字 NewAxisNumeric モジュールで定義)は、長さ1の新しい次元を一つ挿入します。 例えば、a(2, 2) という形状 (shape) だとすると、a[:, Numeric.NewAxis, :](2, 1, 2) という形状で、a と同じ要素を引き継ぎます。

Arrays can also be used as sequences, e.g. in loops. In such a situation, the first index becomes the sequence index, and the elements of the sequences are arrays with a smaller rank. This is a consequence of the rule to assign indices to dimensions starting from the left.

配列を、例えばループ変数の列として用いることも出来ます。この場合、配列の最初の添字が列の添字になり、列の要素はより小さな階数の配列になります。これは、添字を左から各次元に割り当てるという規則に由来するものです。

The standard arithmetic operations (addition, multiplication, etc.) and the mathematical functions from the module Numeric can be applied to arrays, which means that they are applied to each element of the array. For binary operations (addition etc.), the arrays must have matching shapes. However, "matching" does not mean "equal". It is possible, for example, to multiply a whole array by a single number, or to add a row to all rows of a matrix. The precise matching rule is the following: Compare the shapes of the two arrays element by element, starting from the right and continuing until the smaller one is exhausted; if for all dimensions the lengths are equal or one of them is one, then the arrays match. A less rigorous description is that dimensions of length one are repeated along the corresponding dimension of the other array.

配列には、標準的な算術演算(加法、乗法、など)や、Numeric モジュールの算術関数を用いることができます。この場合、それらの演算や関数は、配列の各要素に適用されます。 二数演算(加法など)では、配列の形状 (shape) が適合している必要があります。ただし、ここで "適合" とは "同一" という意味ではありません。例えば、配列全体に一つの数を掛けたり、ある行列の全ての列に他の列を加えることも可能です。 正確な適合の規則は次のようなものです: 二つの配列の形状を各要素ごとに右から比較し、小さな方が尽きるまで続ける; 全ての次元について長さが一致するか、またはどちらかの長さが1であったら、二つの配列は適合している。 より厳密でない言い方をすれば、一方の配列に長さ1の次元があったならば、他方の配列の対応する次元に沿って繰り返されます。

Example / 例:

a = array([[1, 2]])               # shape (1, 2)
b = array([[10], [20], [30]])     # shape (3, 1)
When you ask for a+b, a is repeated three times along the first axis, and b is repeated twice along the second axis, giving

a+b を求めると、a は第一の軸に沿って3回、b は第二の軸に沿って2回繰り返され、結果は次の様になります

a = array([[1, 2], [1, 2], [1, 2]])
b = array([[10, 10], [20, 20], [30, 30]])
Now both arrays have the same shape, and a+b is array([[11, 12], [21, 22], [31, 32]]). Of course the arrays are not physically replicated, so there is no risk of running out of memory.

これで両者は同じ形状となり、a+barray([[11, 12], [21, 22], [31, 32]]) となります。 もちろん、配列が実際に反復されるわけではないので、メモリが足りなくなるといった心配はありません。

Binary operations also exist as functions (in module Numeric): add(a, b) is equivalent to a+b, and subtract, multiply, divide, and power can be used instead of the other binary operators. There are some more binary operations that exist only as functions:

二数演算は(Numeric モジュール中の)関数にもあります:add(a, b)a+b と等価ですし、subtractmultiplydividepower も相当する他の二数演算の代りに使えます。 関数としてのみ存在する二数演算も、もっとあります:
maximum(a, b), minimum(a, b) larger/smaller of a and b a と b の大きい/小さい方
equal(a, b), not_equal(a, b) equality test (returns 0/1) 同一の判定(0 または 1 を返す)
greater(a, b), greater_equal(a, b) comparison 比較
less(a, b), less_equal(a, b) comparison 比較
logical_and(a, b), logical_or(a,b) logical and/or 論理和/積
logical_not(a) logical negation 否定

The binary operations in this list can also be applied to combinations of elements of a single array. For example, add.reduce(a) calculates the sum of all elements of a along the first dimension, and minimum.reduce(a) returns the smallest element in a. An optional second argument indicates the dimension explicitly. It can be positive (0 = first dimension) or negative (-1 = last dimension). A variation is accumulate: add.accumulate(a) returns an array containing the first element of a, the sum of the first two elements, the sum of the first three elements, etc. The last element is then equal to add.reduce(a).

上記の二数演算は、単一の配列中の要素の組に対しても適用できます。 例えば、add.reduce(a)a の第一の次元に沿って全要素の和を計算し、minimum.reduce(a)a の最小の要素を返します。 オプションで第二引数を与えれば、次元を明示することもできます。その場合の引数は正(0 = 最初の次元)でも、負(-1 = 最後の次元)でも使えます。 他にも accumulate というのがあります:add.accumulate(a) は、a の第1要素、初めの2要素の和、初めの3要素の和、… から成る配列を返します。 よって、最後の要素は add.reduce(a) と等しくなります。

Another way to derive an operation from binary functions is outer. add.outer(a, b) returns an array with the combined dimensions of a and b whose elements are all possible sum combinations of the elements of a and b.

二変数関数から一つの演算を引き出す方法には、他に outer があります。 add.outer(a, b) は、ab の各要素の全ての可能な組合せについて和をとったものを要素とし、相当する(結合された)次元を持った配列を返します。

More array operations will be described later.

配列演算については、また後述します。

Functions / 関数

You have already used many Python functions, and may have wished to write your own. Functions allow you to write (and test) a certain piece of code once and then use it again and again. This course will only treat functions defined in Python; it is also possible to define functions in C or compatible low-level languages.

すでに多くの Python 関数を使ったので、自分のものを書きたいと思ったかも知れません。 関数を使えば、一度書いた(またテストした)プログラムをまた何度も使うことができます。 このコースでは Python で関数を定義する場合のみを扱いますが、C 言語または適当な低級言語によって関数を定義することも可能です。

The following code example defines a function called distance that calculates the distance between two points in space, and calls this function for two arbitrary vectors:

次のプログラム例は、空間の二点間の距離を計算する distance という名の関数を定義し、二つの適当なベクトルについてその関数を呼びます:

from Scientific.Geometry import Vector

def distance(r1, r2):
    return (r1-r2).length()

print distance(Vector(1., 0., 0.), Vector(3., -2., 1.))

You can imagine a function call as consisting of three steps:

関数呼び出しは、次の三段階からなると考えることができます:

  1. The arguments in the function call are assigned to the corresponding variables in the function definition.
  2. The code in the function is executed.
  3. The value given to the return statement is put in the place of the original function call.
  1. 関数に渡された引数が、関数定義中の対応する変数に割り当てられる。
  2. 関数中の演算が実行される。
  3. return 文に渡された値が、元の関数の呼ばれた所に置かれる。

Functions can take any number of arguments (including zero), and return any number of values (including zero). They can also define any number of variables. These variables are local to the function, i.e. they have no relation to variables of the same name in another function or outside any function. However, function may use (but not change) the value of variables defined outside them. The function argument variables are also local to the function. Inside the function, they can be used like any other variable.

関数の引数および返値の個数はともに任意(ゼロも含む)です。 関数は任意の個数の変数を定義できます。それらの変数はその関数に局所的(local)です。すなわち、他の関数や関数の外部に同じ名前の変数があっても、それらは無関係です。 しかし、関数はその外部で定義された変数の値を使うことは許されています。 関数の引数も、その関数に局所的となり、関数の内部では他の変数と同様に使えます。

The following function converts cartesian to polar coordinates. It takes two arguments and returns two values. It also defines local variables.

次の関数は、直交座標を極座標に変換します。二つの引数を受け取り、二つの値を返します。 局所変数も定義しています。

import Numeric

def cartesianToPolar(x, y):
    r = Numeric.sqrt(x**2+y**2)
    phi = Numeric.arccos(x/r)
    if y < 0.:
        phi = 2.*Numeric.pi-phi
    return r, phi

radius, angle = cartesianToPolar(1., 1.)
print radius
print angle

Functions are just a special kind of data objects. Like all other data objects, they can be assigned to variables, stored in lists and dictionaries, or passed as arguments to other function. The following example shows a function that prints a table of values of another function that it receives as an argument:

関数は、特別な種類のデータオブジェクトにすぎません。 他の全てのデータオブジェクトと同様に、関数を変数に割り当てたり、リストや辞書に格納したり、他の関数に引数として渡したりすることが可能です。 次の例で示す関数は、引数として他の関数を受け取り、その値を表にして印字します。

import Numeric

def printTable(function, first_value, last_value, step):
    for x in Numeric.arrayrange(first_value, last_value, step):
	print x, function(x)


def someFunction(x):
    return Numeric.sin(x**2)

printTable(someFunction, 0., 5., 0.1)

Modules / モジュール

Until now all programs have been written as single files containing everything necessary, and importing definitions from standard modules. A function to be used in several programs would have to be copied to several files, which is not very practical. Such generally useful definitions should be collected in modules.

ここまでのプログラムは全て、標準モジュールから取り入れた定義の他に必要なものは全て自身で持つような、単一のファイルとして書かれていました。 この場合、複数のプログラムで使われる関数はそれぞれのファイルにコピーされなくてはなりませんが、これは余り実用的ではありません。 そのような一般的に有用な定義は、モジュールに集めておくべきです。

Python makes no difference between its standard library and any other modules; the standard library just happens to come with the interpreter. The mechanisms for importing from modules are the same, irrespective of the origin.

Python は標準ライブラリと他のモジュールを区別しません;標準ライブラリは、単にたまたまインタープリタが始めから装備しているに過ぎないわけです。 それが何処からであるかに関わらず、モジュールから取り込む仕組みは同一です。

A module is simply a file containing definitions (variables, functions, etc.). The name of the file must end in .py; everything before that makes up the module name. The command import Numeric, for example, looks for a file called Numeric.py and executes it, making the resulting definitions available to the importing program.

モジュールは単に、定義(変数、関数など)からなるファイルです。 ファイル名は、.py で終らなくてはなりません;その前がモジュール名になります。 例えば、import Numeric という命令は、Numeric.py という名前のファイルを探して実行し、その結果得られる定義を、取り込み元のプログラムが使えるようにします。

However, Python does not search the whole file system for modules; that would be inefficient and dangerous. It uses a strategy similar to that used by Unix to locate programs: an environment variable called PYTHONPATH can be set before running Python, and its value must be a sequence of directory names separated by colons. Python looks for modules in those directories in the specified order; if a module is not found there, Python tries its standard library.

しかし、Python はファイルシステム全体からモジュールを探すことはしません;それは非能率的で危険でしょう。 Python は Unix がファイルの場所を指定するのに用いているのと類似の方法を使います:Python を実行する前に、PYTHONPATH という名の環境変数を設定することができます。 コロンで区切った一連のディレクトリ名をその値とします。 Python は、指示された順でディレクトリ中のモジュールを探します;モジュールが見つからなかった場合は、標準ライブラリの検索を試みます。

Some of the module names that have been used before contain one or several dots. These are modules contained in packages. A package is a module that contains other modules. Packages are used to structure libraries and to prevent name clashes between libraries written by different people. The only package used so far is Scientific, which contains the modules Geometry and IO (plus others). And these modules are themselves packages; IO for example contains the modules TextFile and FortranFormat that have been used before. A full description of the package Scientific can be found in its manual.

これまでに使ったモジュールには、名前に幾つかのドット(点)を含むものがありました。 これらのモジュールは、パッケージに含まれています。 パッケージは、他のモジュールを含むモジュールです。 ライブラリを構造化し、相異なる人々によって書かれたライブラリ間の名前の衝突を防ぐために、パッケージを使います。 ここまでに使ったパッケージは Scientific だけで、GeometryIO(他にもあります)といったモジュールを含んでいました。 しかも、これらのモジュールはそれ自身がパッケージになっています;例えば IO は、以前使った TextFileFortranFormat モジュールを含んでいます。 Scientific パッケージ全体の説明はマニュアルにあります。

Programs with parameters / パラメータ付きプログラム

You may also want to write Python programs for regular use that take parameters from the shell command line, i.e. you might want to run a program as

よく使う Python プログラムを書く際に、シェルのコマンド行からパラメータを受け取るようにしたい、すなわち、プログラムを次のように実行したい場合もあるでしょう。

python my_program.py a b c
All you need to achieve this is a way to access the command line parameters. The module sys contains a variable argv whose value is a list of all parameters, starting with the name of the Python program. So in the example above, sys.argv would be ['my_program.py', 'a', 'b', 'c'].

これには、コマンド行中のパラメータを参照する方法があれば良いわけです。 sys モジュールには、argv という変数があり、それは全パラメータのリストを値として持ちます。リストの最初の値はその Python プログラムの名前になります。 上の例では、sys.argv['my_program.py', 'a', 'b', 'c'] です。

On Unix systems, you can even make Python programs directly executable. This requires two steps: first, add

#!/usr/local/bin/python
as the first line of your Python program. You must change the path if Python is installed somewhere else on your system. Second, make the file executable with the Unix utility chmod.

Unix システムでは、Python プログラムを直接起動するようにもできます。 これには二つの手続きが必要です:まず、Python プログラムの最初の行に

#!/usr/local/bin/python
という行を加えます。 Python が他の場所にインストールされているならば、パス名を変える必要があります。 次に、Unix の chmod コマンドによって、そのプログラムファイルを実行可能にします。

The magical line shown above is ignored by Python, since it is a comment (a line starting with #). But it is recognized by the Unix shells as an indicator of the program that must be run to execute the file.

Python は、上のおまじないのような行を無視します。 それはコメント(# で始まる行)と見なされるからです。 しかし、Unix シェルはその行を認識して、そのファイルを実行するために起動するべきプログラムを指示するものと見なします。

Statistics / 統計

The module Scientific.Statistics contains some elementary statistical analysis functions.

Scientific.Statistics モジュールには、初歩的な統計解析の関数が含まれています。

The functions average(data), variance(data) and standardDeviation(data) all take a sequence of data values and return the statistical quantity indicated by their name.

average(data)(平均)、variance(data)(分散)、standardDeviation(data)(標準偏差)といった関数は、いずれもデータ値の列を受け取り、その名の示す統計量を返します。

The submodule Histogram defines a histogram object. Histogram(data, number_of_bins) takes a sequence of data and calculates a histogram by dividing the range of the data into the specified number of bins and counting how many data values fall within each bin interval. An optional third argument is a tuple specifying the range to be analyzed (lower and upper bound). A histogram is an array of rank two representing a sequence of bins, with each bin being described by its center and its count.

Histogram という副モジュールは、棒グラフオブジェクトを定義します。 Histogram(data, number_of_bins) は、データの列を受け取り、データ範囲を指定された個数の箱に分け、各々の箱に幾つのデータ値が入るかを勘定して、棒グラフを計算します。 オプションで三番目の引数に、解析する範囲(下限と上限)を指定するタプルを渡すこともできます。 ヒストグラムは、階数2の配列によって箱の列を表したもので、各々の箱にはその中心値とカウント数が記されています。

Plotting / 図示

There is no full-featured plotting module for Python yet. For the moment, plotting is delegated to external programs. There are two modules that contain a function for simple line plots: Scientific.Mathematica and Gnuplot. They use the external program indicated by their name. Both modules define a function called plot, and both versions behave in a compatible way.

Python には、専用の図示用モジュールはまだありません。 とりあえず、図示は外部プログラムに委ねられています。 簡単な線図表示用の関数を含むモジュールは二つあります: Scientific.MathematicaGnuplot です。 これらは、その名の示す外部プログラムを利用します。 これらのモジュールは、共に plot という名の関数を定義しており、振る舞いはいずれも共通です。

The function plot takes an arbitrary number of arguments, each specifying a dataset. All datasets will be plotted in the same graph. A dataset is a sequence of points. A point is specified by a two-element sequence (x and y coordinates) or by a simple number, which is interpreted as the y coordinate, the x coordinate being the index of the point in the sequence.

plot 関数は、任意の個数の引数を受け取ります。 引数の各々が一つのデータセットを指定し、それらは同じグラフに表示されます。 各データセットは点の列です。 一点は、二要素から成る列(x、y座標)または単一の数、で指定されます。 後者の場合、その数がy座標と見なされ、x座標は列においてその点を表す添字になります。

The function plot also takes an optional keyword argument of the form file='something.ps'. When this argument is present, the plot will be written to the specified file in PostScript format.

plot 関数には、file='something.ps' という形式のキーワード引数 を受け取るオプションがあります。 この引数があると、図は指定されたファイルにポストスクリプト形式で書き出されます。

Example / 例:

from Gnuplot import plot
from Scientific.Statistics.Histogram import Histogram
from Numeric import arrayrange, sqrt

plot(Histogram(sqrt(arrayrange(100.)), 10))

Exercises / 練習問題


Table of Contents / 目次