pandas ドキュメントストリングガイド#
ドキュメントストリングと標準について#
Pythonのドキュメントストリングは、Pythonのモジュール、クラス、関数、メソッドを文書化するために使用される文字列であり、プログラマーが実装の詳細を読まなくてもその動作を理解できるようにするためのものです。
また、ドキュメントストリングから自動的にオンライン(HTML)ドキュメントを生成するのが一般的な慣行です。 Sphinxはこの目的で使用されます。
次の例は、ドキュメントストリングがどのようなものかを示しています。
def add(num1, num2):
"""
Add up two integer numbers.
This function simply wraps the ``+`` operator, and does not
do anything interesting, except for illustrating what
the docstring of a very simple function looks like.
Parameters
----------
num1 : int
First number to add.
num2 : int
Second number to add.
Returns
-------
int
The sum of ``num1`` and ``num2``.
See Also
--------
subtract : Subtract one integer from another.
Examples
--------
>>> add(2, 2)
4
>>> add(25, 0)
25
>>> add(10, -10)
0
"""
return num1 + num2
ドキュメントストリングに関するいくつかの標準が存在し、それらを読むのが容易になり、HTMLやPDFなどの他の形式に簡単にエクスポートできるようになります。
すべてのPythonドキュメントストリングが従うべき最初の規約は、PEP-257で定義されています。
PEP-257は非常に広範であるため、より具体的な標準も存在します。pandasの場合、NumPyドキュメントストリングの規約に従います。これらの規約については、このドキュメントで説明します。
numpydocは、NumPyドキュメントストリングの規約をサポートするSphinx拡張機能です。
この標準では、reStructuredText(reST)を使用します。reStructuredTextは、プレーンテキストファイルでスタイルをエンコードできるマークアップ言語です。reStructuredTextに関するドキュメントは、以下にあります。
pandasには、関連するクラス間でドキュメントストリングを共有するためのヘルパーがいくつかあります。詳細については、ドキュメントストリングの共有を参照してください。
このドキュメントの残りの部分では、上記のガイドラインをすべてまとめ、pandasプロジェクトに固有の追加の規約を提供します。
ドキュメントストリングの記述#
一般的なルール#
ドキュメントストリングは、3つのダブルクォートで定義する必要があります。ドキュメントストリングの前後に空行を残してはなりません。テキストは、開始クォートの次の行から始まります。終了クォートは独自の行を持ちます(つまり、最後の文の末尾にはありません)。
まれに、ドキュメントストリングで太字や斜体などのreSTスタイルが使用されますが、バッククォートで囲まれたインラインコードを使用するのが一般的です。以下はインラインコードと見なされます。
パラメーターの名前
Pythonコード、モジュール、関数、組み込み、型、リテラル...(例:
os
、list
、numpy.abs
、datetime.date
、True
)pandasクラス(
:class:`pandas.Series`
の形式)pandasメソッド(
:meth:`pandas.Series.sum`
の形式)pandas関数(
:func:`pandas.to_datetime`
の形式)
注意
リンクされたクラス、メソッド、または関数の最後のコンポーネントのみを表示するには、~
を先頭に付けます。たとえば、:class:`~pandas.Series`
はpandas.Series
にリンクしますが、リンクテキストとして最後の部分であるSeries
のみが表示されます。詳細については、Sphinxの相互参照構文を参照してください。
良い例
def add_values(arr):
"""
Add the values in ``arr``.
This is equivalent to Python ``sum`` of :meth:`pandas.Series.sum`.
Some sections are omitted here for simplicity.
"""
return sum(arr)
悪い例
def func():
"""Some function.
With several mistakes in the docstring.
It has a blank like after the signature ``def func():``.
The text 'Some function' should go in the line after the
opening quotes of the docstring, not in the same line.
There is a blank line between the docstring and the first line
of code ``foo = 1``.
The closing quotes should be in the next line, not in this one."""
foo = 1
bar = 2
return foo + bar
セクション1:短い要約#
短い要約は、関数が何をするかを簡潔に表現する単一の文です。
短い要約は大文字で始まり、ドットで終わり、1行に収まる必要があります。詳細を提供せずに、オブジェクトが何をするかを表現する必要があります。関数とメソッドの場合、短い要約は不定詞の動詞で始まる必要があります。
良い例
def astype(dtype):
"""
Cast Series type.
This section will provide further details.
"""
pass
悪い例
def astype(dtype):
"""
Casts Series type.
Verb in third-person of the present simple, should be infinitive.
"""
pass
def astype(dtype):
"""
Method to cast Series type.
Does not start with verb.
"""
pass
def astype(dtype):
"""
Cast Series type
Missing dot at the end.
"""
pass
def astype(dtype):
"""
Cast Series type from its current type to the new type defined in
the parameter dtype.
Summary is too verbose and doesn't fit in a single line.
"""
pass
セクション2:拡張された要約#
拡張された要約は、関数が何をするかの詳細を提供します。パラメーターの詳細や、他のセクションに記述する実装に関する注意事項については説明しないでください。
短い要約と拡張された要約の間には空行が残されます。拡張された要約のすべての段落はドットで終わります。
拡張された要約は、関数がなぜ有用なのか、およびそのユースケース(あまり一般的でない場合)について詳細を提供する必要があります。
def unstack():
"""
Pivot a row index to columns.
When using a MultiIndex, a level can be pivoted so each value in
the index becomes a column. This is especially useful when a subindex
is repeated for the main index, and data is easier to visualize as a
pivot table.
The index level will be automatically removed from the index when added
as columns.
"""
pass
セクション3:パラメーター#
パラメーターの詳細は、このセクションに追加されます。このセクションには「Parameters」というタイトルがあり、その後に「Parameters」という単語の各文字の下にハイフンが付いた行が続きます。セクションタイトルの前には空行が残されますが、後には残されません。また、「Parameters」という単語がある行とハイフンがある行の間にも残されません。
タイトルの後、シグネチャ内の各パラメーター(*args
と**kwargs
を含むが、self
は含まない)を文書化する必要があります。
パラメーターは、名前、その後にスペース、コロン、別のスペース、および型(または型)で定義されます。名前とコロンの間のスペースが重要であることに注意してください。*args
と**kwargs
には型は定義されませんが、他のすべてのパラメーターには定義する必要があります。パラメーター定義の後には、パラメーターの説明が記述された行が必要であり、インデントされ、複数行にすることができます。説明は大文字で始まり、ドットで終わる必要があります。
デフォルト値を持つキーワード引数の場合、デフォルト値は型の末尾にコンマを付けてリストされます。この場合の型の正確な形式は、「int, default 0」になります。場合によっては、デフォルトの引数が何を意味するのかを説明すると便利な場合があります。これは、コンマ「int, default -1, meaning all cpus」の後に追加できます。
デフォルト値がNone
の場合(つまり、値が使用されない場合)。"str, default None"
の代わりに、"str, optional"
と記述することをお勧めします。None
が使用される値である場合、「str, default None」という形式を維持します。たとえば、df.to_csv(compression=None)
では、None
は使用される値ではなく、圧縮がオプションであり、指定されていない場合は圧縮が使用されないことを意味します。この場合、"str, optional"
を使用します。func(value=None)
のようにNone
が0
やfoo
と同じように使用されている場合にのみ、「str, int or None, default None」を指定します。
良い例
class Series:
def plot(self, kind, color='blue', **kwargs):
"""
Generate a plot.
Render the data in the Series as a matplotlib plot of the
specified kind.
Parameters
----------
kind : str
Kind of matplotlib plot.
color : str, default 'blue'
Color name or rgb code.
**kwargs
These parameters will be passed to the matplotlib plotting
function.
"""
pass
悪い例
class Series:
def plot(self, kind, **kwargs):
"""
Generate a plot.
Render the data in the Series as a matplotlib plot of the
specified kind.
Note the blank line between the parameters title and the first
parameter. Also, note that after the name of the parameter ``kind``
and before the colon, a space is missing.
Also, note that the parameter descriptions do not start with a
capital letter, and do not finish with a dot.
Finally, the ``**kwargs`` parameter is missing.
Parameters
----------
kind: str
kind of matplotlib plot
"""
pass
パラメーターの型#
パラメーターの型を指定する場合、Python組み込みデータ型を直接使用できます(より冗長な文字列、整数、ブール値などよりもPython型が推奨されます)。
int
float
str
bool
複合型の場合は、サブタイプを定義します。dict
とtuple
の場合、複数の型が存在するため、型を読みやすくするために括弧を使用します(dict
の場合は中括弧、tuple
の場合は通常の括弧)。
intのリスト
{str : int} の辞書
(str, int, int) のタプル
(str,) のタプル
str の集合
許可されている値のセットのみがある場合は、中括弧で囲んでカンマ(その後にスペース)で区切ってリストします。値が順序付け可能で、順序がある場合は、この順序でリストします。それ以外の場合は、デフォルト値がある場合は最初にリストします。
{0, 10, 25}
{‘simple’, ‘advanced’}
{‘low’, ‘medium’, ‘high’}
{‘cat’, ‘dog’, ‘bird’}
型がPythonモジュールで定義されている場合は、モジュールを指定する必要があります。
datetime.date
datetime.datetime
decimal.Decimal
型がパッケージにある場合は、モジュールも指定する必要があります。
numpy.ndarray
scipy.sparse.coo_matrix
型がpandas型の場合は、SeriesとDataFrameを除いてpandasも指定します。
Series
DataFrame
pandas.Index
pandas.Categorical
pandas.arrays.SparseArray
正確な型が重要ではなく、NumPy配列と互換性がある必要がある場合は、array-likeを指定できます。反復可能な型が受け入れられる場合は、iterableを使用できます。
array-like
iterable
複数の型が受け入れられる場合は、カンマで区切ります。ただし、最後の2つの型は「or」という単語で区切る必要があります。
int or float
float, decimal.Decimal or None
str or list of str
None
が許容される値の1つである場合、常にリストの最後に置く必要があります。
軸については、次のような表記が慣例です。
axis : {0 or ‘index’, 1 or ‘columns’, None}, default None
セクション4: 戻り値または yield#
メソッドが値を返す場合、このセクションで説明します。メソッドがその出力を yield する場合も同様です。
セクションのタイトルは、「Parameters」と同じ方法で定義されます。「Returns」または「Yields」という名前の後に、先行する単語の文字数と同じ数のハイフンを並べた行が続きます。
戻り値の説明もパラメーターに似ています。ただし、この場合、メソッドが複数の値(値のタプル)を返すか yield する場合を除き、名前は提供されません。
「Returns」と「Yields」の型は、「Parameters」の型と同じです。また、説明は必ずドットで終わる必要があります。
たとえば、単一の値の場合
def sample():
"""
Generate and return a random number.
The value is sampled from a continuous uniform distribution between
0 and 1.
Returns
-------
float
Random number generated.
"""
return np.random.random()
複数の値の場合
import string
def random_letters():
"""
Generate and return a sequence of random letters.
The length of the returned string is also random, and is also
returned.
Returns
-------
length : int
Length of the returned string.
letters : str
String of random letters.
"""
length = np.random.randint(1, 10)
letters = ''.join(np.random.choice(string.ascii_lowercase)
for i in range(length))
return length, letters
メソッドが値を yield する場合
def sample_values():
"""
Generate an infinite sequence of random numbers.
The values are sampled from a continuous uniform distribution between
0 and 1.
Yields
------
float
Random number generated.
"""
while True:
yield np.random.random()
セクション5: 関連項目#
このセクションは、ユーザーがドキュメント化されている pandas の機能に関連する情報を知るために使用されます。まれに、関連するメソッドや関数がまったく見つからない場合は、このセクションをスキップできます。
明らかな例としては、head()
メソッドと tail()
メソッドが挙げられます。tail()
は head()
と同等の処理を Series
または DataFrame
の先頭ではなく末尾で行うため、ユーザーにそのことを知らせることは良いことです。
何が関連すると考えられるかについて直感を与えるために、いくつかの例を挙げます。
loc
とiloc
は、同じことを行いますが、一方ではインデックスを提供し、もう一方では位置を提供します。max
とmin
は、反対のことを行います。iterrows
、itertuples
、items
は、列を反復処理するためのメソッドを探しているユーザーが行を反復処理するためのメソッドにたどり着いたり、その逆もまた然り、ということが容易に起こりうるからです。fillna
とdropna
は、どちらのメソッドも欠損値を処理するために使用されます。read_csv
とto_csv
は、相補的な関係にあります。merge
とjoin
は、一方が他方の一般化です。astype
とpandas.to_datetime
は、ユーザーが日付としてキャストする方法を知るためにastype
のドキュメントを読んでいる可能性があり、その方法はpandas.to_datetime
であるからです。where
はnumpy.where
に関連しています。その機能がそれに基づいているからです。
何が関連するかを判断する際には、主に常識を働かせ、ドキュメントを読んでいるユーザー、特に経験の浅いユーザーにとって何が役立つかを考える必要があります。
他のライブラリ(主に numpy
)に関連付ける場合は、まずモジュールの名前(np
のようなエイリアスではない)を使用します。関数がメインではないモジュール(scipy.sparse
など)にある場合は、モジュール全体(例:scipy.sparse.coo_matrix
)をリストします。
このセクションには、「See Also」(S と A が大文字であることに注意)という見出しがあり、その後にハイフンの行が続き、その前に空白行が置かれます。
見出しの後には、関連するメソッドまたは関数ごとに1行追加し、その後にスペース、コロン、別のスペース、そしてそのメソッドまたは関数が何をするか、このコンテキストでなぜ関連するのか、そしてドキュメント化された関数と参照される関数の主な違いは何かを説明する短い説明を記述します。説明もドットで終わる必要があります。
「Returns」と「Yields」では、説明は型の後の行に記載されていることに注意してください。ただし、このセクションでは、同じ行にコロンを挟んで記載されます。説明が同じ行に収まらない場合は、さらにインデントされた他の行に続けることができます。
例を以下に示します。
class Series:
def head(self):
"""
Return the first 5 elements of the Series.
This function is mainly useful to preview the values of the
Series without displaying the whole of it.
Returns
-------
Series
Subset of the original series with the 5 first values.
See Also
--------
Series.tail : Return the last 5 elements of the Series.
Series.iloc : Return a slice of the elements in the Series,
which can also be used to return the first or last n.
"""
return self.iloc[:5]
セクション6: 注釈#
これは、アルゴリズムの実装に関する注記や、関数の動作に関する技術的な側面をドキュメント化するために使用されるオプションのセクションです。
アルゴリズムの実装に精通しているか、関数の例を作成中に何か直感的でない動作を発見した場合を除き、スキップしても構いません。
このセクションは、拡張された概要セクションと同じ形式に従います。
セクション7: 例#
これは、ドキュメント文字列の中で最も重要なセクションの1つです。最後の方に配置されていますが、多くの場合、人々は正確な説明よりも例を通して概念を理解するからです。
ドキュメント文字列の例は、関数またはメソッドの使用法を示すだけでなく、有効な Python コードである必要があり、決定論的な方法で与えられた出力を返し、ユーザーがコピーして実行できる必要があります。
例は、Python ターミナルでのセッションとして提示されます。コードを提示するには >>>
を使用します。前の行から続くコードには ...
を使用します。出力は、出力を生成するコードの最後の行の直後に提示されます(間に空白行はありません)。例を説明するコメントは、その前後に空白行を追加して記述できます。
例を提示する方法は次のとおりです。
numpy
およびpandas
を除く、必要なライブラリをインポートします。例に必要なデータを作成します。
最も一般的なユースケースのアイデアを示す非常に基本的な例を示します。
拡張機能のためにパラメーターをどのように使用できるかを説明する例を追加します。
簡単な例を次に示します。
class Series:
def head(self, n=5):
"""
Return the first elements of the Series.
This function is mainly useful to preview the values of the
Series without displaying all of it.
Parameters
----------
n : int
Number of values to return.
Return
------
pandas.Series
Subset of the original series with the n first values.
See Also
--------
tail : Return the last n elements of the Series.
Examples
--------
>>> ser = pd.Series(['Ant', 'Bear', 'Cow', 'Dog', 'Falcon',
... 'Lion', 'Monkey', 'Rabbit', 'Zebra'])
>>> ser.head()
0 Ant
1 Bear
2 Cow
3 Dog
4 Falcon
dtype: object
With the ``n`` parameter, we can change the number of returned rows:
>>> ser.head(n=3)
0 Ant
1 Bear
2 Cow
dtype: object
"""
return self.iloc[:n]
例はできるだけ簡潔にする必要があります。関数の複雑さにより長い例が必要な場合は、ヘッダーを太字にしたブロックを使用することをお勧めします。テキストを太字にするには、二重アスタリスク **
を使用します(**この例**
など)。
例の規約#
例のコードは、常に次の2行で始まることが前提とされていますが、これは表示されません。
import numpy as np
import pandas as pd
例で使用されるその他のモジュールは、明示的にインポートする必要があります。1行に1つずつ(PEP 8#imports で推奨されているように)で、エイリアスは避けてください。過度なインポートは避けてください。ただし、必要な場合は、標準ライブラリからのインポートを最初に行い、その後にサードパーティ製ライブラリ(matplotlib など)が続きます。
単一の Series
を使用した例を示す場合は名前 ser
を使用し、単一の DataFrame
を使用して例を示す場合は名前 df
を使用します。インデックスには、idx
が推奨される名前です。同種の Series
または DataFrame
のセットを使用する場合は、ser1
、ser2
、ser3
… または df1
、df2
、df3
… という名前を付けます。データが同種ではなく、複数の構造が必要な場合は、df_main
や df_to_join
など、意味のある名前を付けます。
例で使用するデータは、できるだけコンパクトにする必要があります。行数は4行程度にすることをお勧めしますが、特定の例で意味のある数にします。たとえば、head
メソッドでは、デフォルト値の例を示すために5より大きい必要があります。mean
を行う場合は、[1, 2, 3]
のようにして、返される値が平均であることが簡単にわかるようにします。
より複雑な例(たとえばグループ化)では、A、B、C、D… 列を持つ乱数の行列のような解釈のないデータを使用することは避けてください。代わりに、概念を理解しやすくする意味のある例を使用してください。例で必要な場合を除き、例の一貫性を保つために動物の名前を使用してください。また、それらの数値プロパティを使用してください。
メソッドを呼び出す場合は、位置引数 head(3)
よりもキーワード引数 head(n=3)
を優先します。
良い例
class Series:
def mean(self):
"""
Compute the mean of the input.
Examples
--------
>>> ser = pd.Series([1, 2, 3])
>>> ser.mean()
2
"""
pass
def fillna(self, value):
"""
Replace missing values by ``value``.
Examples
--------
>>> ser = pd.Series([1, np.nan, 3])
>>> ser.fillna(0)
[1, 0, 3]
"""
pass
def groupby_mean(self):
"""
Group by index and return mean.
Examples
--------
>>> ser = pd.Series([380., 370., 24., 26],
... name='max_speed',
... index=['falcon', 'falcon', 'parrot', 'parrot'])
>>> ser.groupby_mean()
index
falcon 375.0
parrot 25.0
Name: max_speed, dtype: float64
"""
pass
def contains(self, pattern, case_sensitive=True, na=numpy.nan):
"""
Return whether each value contains ``pattern``.
In this case, we are illustrating how to use sections, even
if the example is simple enough and does not require them.
Examples
--------
>>> ser = pd.Series('Antelope', 'Lion', 'Zebra', np.nan)
>>> ser.contains(pattern='a')
0 False
1 False
2 True
3 NaN
dtype: bool
**Case sensitivity**
With ``case_sensitive`` set to ``False`` we can match ``a`` with both
``a`` and ``A``:
>>> s.contains(pattern='a', case_sensitive=False)
0 True
1 False
2 True
3 NaN
dtype: bool
**Missing values**
We can fill missing values in the output using the ``na`` parameter:
>>> ser.contains(pattern='a', na=False)
0 False
1 False
2 True
3 False
dtype: bool
"""
pass
悪い例
def method(foo=None, bar=None):
"""
A sample DataFrame method.
Do not import NumPy and pandas.
Try to use meaningful data, when it makes the example easier
to understand.
Try to avoid positional arguments like in ``df.method(1)``. They
can be all right if previously defined with a meaningful name,
like in ``present_value(interest_rate)``, but avoid them otherwise.
When presenting the behavior with different parameters, do not place
all the calls one next to the other. Instead, add a short sentence
explaining what the example shows.
Examples
--------
>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame(np.random.randn(3, 3),
... columns=('a', 'b', 'c'))
>>> df.method(1)
21
>>> df.method(bar=14)
123
"""
pass
ドクトテストをパスするためのヒント#
検証スクリプトで例がドクトテストをパスするのが難しい場合があります。注意すべき点を以下に示します。
必要なライブラリをすべてインポートしてください(pandasとNumPyを除く。これらはすでに
import pandas as pd
およびimport numpy as np
としてインポートされています)。また、例で使用するすべての変数を定義してください。ランダムデータを使用することは避けてください。ただし、ドキュメント化している関数が確率分布を扱う場合や、関数の結果を有意義にするために必要なデータ量が非常に多く、手動で作成するのが非常に面倒な場合は、ランダムデータを使用しても構いません。これらの場合、生成された例を予測可能にするために、常に固定のランダムシードを使用してください。例:
>>> np.random.seed(42) >>> df = pd.DataFrame({'normal': np.random.normal(100, 5, 20)})
複数行にわたるコードスニペットがある場合は、継続行に「...」を使用する必要があります。
>>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], index=['a', 'b', 'c'], ... columns=['A', 'B'])
例外が発生するケースを示したい場合は、次のように記述できます。
>>> pd.to_datetime(["712-01-01"]) Traceback (most recent call last): OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 712-01-01 00:00:00
「Traceback (most recent call last):」を含めることは必須ですが、実際のエラーについては、エラー名のみで十分です。
結果の一部が変動する可能性がある場合(例:オブジェクト表現のハッシュ)、この部分を表すために
...
を使用できます。s.plot()
がmatplotlib AxesSubplotオブジェクトを返すことを示したい場合、これはdoctestに失敗します。>>> s.plot() <matplotlib.axes._subplots.AxesSubplot at 0x7efd0c0b0690>
ただし、(追加する必要があるコメントに注意して)次のように記述できます。
>>> s.plot() <matplotlib.axes._subplots.AxesSubplot at ...>
例のプロット#
pandasには、プロットを返すメソッドがいくつかあります。ドキュメント内の例によって生成されたプロットをレンダリングするために、.. plot::
ディレクティブが存在します。
それを使用するには、以下に示すように「Examples」ヘッダーの後に次のコードを配置します。ドキュメントをビルドするときに、プロットが自動的に生成されます。
class Series:
def plot(self):
"""
Generate a plot with the ``Series`` data.
Examples
--------
.. plot::
:context: close-figs
>>> ser = pd.Series([1, 2, 3])
>>> ser.plot()
"""
pass