データ分析のための構造化データ出力

PythonPythonBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

このセクションは少し逸脱していますが、データを扱う際には、構造化された出力(表など)を生成したい場合がよくあります。たとえば:

      Name      Shares        Price
----------  ----------  -----------
        AA         100        32.20
       IBM          50        91.10
       CAT         150        83.44
      MSFT         200        51.23
        GE          95        40.37
      MSFT          50        65.10
       IBM         100        70.44

文字列の書式設定

Python 3.6以降で文字列を書式設定する方法の1つは、f-文字列を使うことです。

>>> name = 'IBM'
>>> shares = 100
>>> price = 91.1
>>> f'{name:>10s} {shares:>10d} {price:>10.2f}'
'       IBM        100      91.10'
>>>

{式:書式}の部分が置き換えられます。

これは一般的にprintとともに使用されます。

print(f'{name:>10s} {shares:>10d} {price:>10.2f}')

書式コード

書式コード({}内の:の後)はC言語のprintf()に似ています。一般的なコードは以下の通りです。

d       10進整数
b       2進整数
x       16進整数
f       [-]m.dddddd形式の浮動小数点数
e       [-]m.dddddde+-xx形式の浮動小数点数
g       浮動小数点数で、E表記の選択的な使用
s       文字列
c       整数からの文字

一般的な修飾子はフィールド幅と小数精度を調整します。これは一部のリストです。

:>10d   10文字のフィールド内で右寄せの整数
:<10d   10文字のフィールド内で左寄せの整数
:^10d   10文字のフィールド内で中央寄せの整数
:0.2f   2桁の精度を持つ浮動小数点数

辞書の書式設定

値の辞書に文字列の書式設定を適用するには、format_map()メソッドを使用できます。

>>> s = {
    'name': 'IBM',
   'shares': 100,
    'price': 91.1
}
>>> '{name:>10s} {shares:10d} {price:10.2f}'.format_map(s)
'       IBM        100      91.10'
>>>

これはf-文字列と同じコードを使用しますが、提供された辞書から値を取得します。

format() メソッド

引数またはキーワード引数に書式設定を適用できるformat()メソッドがあります。

>>> '{name:>10s} {shares:10d} {price:10.2f}'.format(name='IBM', shares=100, price=91.1)
'       IBM        100      91.10'
>>> '{:>10s} {:10d} {:10.2f}'.format('IBM', 100, 91.1)
'       IBM        100      91.10'
>>>

正直なところ、format()は少し冗長です。私はf-文字列の方が好きです。

Cスタイルの書式設定

書式設定演算子%も使用できます。

>>> 'The value is %d' % 3
'The value is 3'
>>> '%5d %-5d %10d' % (3,4,5)
'    3 4              5'
>>> '%0.2f' % (3.1415926,)
'3.14'

これには右辺に単一の項目またはタプルが必要です。書式コードもまたC言語のprintf()に基づいています。

注:これはバイト文字列で利用可能な唯一の書式設定です。

>>> b'%s has %d messages' % (b'Dave', 37)
b'Dave has 37 messages'
>>> b'%b has %d messages' % (b'Dave', 37)  ## %bは%sの代わりに使用できます
b'Dave has 37 messages'
>>>

演習2.8:数値の書式設定方法

数値を表示する際の一般的な問題は、小数桁数を指定することです。これを解決する方法の1つは、f-文字列の使用です。これらの例を試してみてください。

>>> value = 42863.1
>>> print(value)
42863.1
>>> print(f'{value:0.4f}')
42863.1000
>>> print(f'{value:>16.2f}')
        42863.10
>>> print(f'{value:<16.2f}')
42863.10
>>> print(f'{value:*>16,.2f}')
*******42,863.10
>>>

f-文字列で使用される書式設定コードの完全なドキュメントは、ここで見つけることができます。書式設定は、時々文字列の%演算子を使用しても行われます。

>>> print('%0.4f' % value)
42863.1000
>>> print('%16.2f' % value)
        42863.10
>>>

%と共に使用されるさまざまなコードのドキュメントは、ここで見つけることができます。

printと共に一般的に使用されますが、文字列の書式設定は印刷に縛られるものではありません。フォーマット済みの文字列を保存したい場合は、変数に割り当てるだけです。

>>> f = '%0.4f' % value
>>> f
'42863.1000'
>>>

演習2.9:データの収集

演習2.7では、株式ポートフォリオの損益を計算するreport.pyというプログラムを書きました。この演習では、これを次のような表を生成するように修正し始めます。

名前 株数 価格 変動
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84

このレポートでは、「価格」は株式の現在の株価であり、「変動」は初期購入価格からの株価の変動です。

上記のレポートを生成するには、まず表に表示されるすべてのデータを収集する必要があります。株式のリストと価格の辞書を入力として受け取り、上記の表の行を含むタプルのリストを返すmake_report()関数を書きます。

この関数をreport.pyファイルに追加します。対話的に試した場合の動作方法は次のとおりです。

>>> portfolio = read_portfolio('/home/labex/project/portfolio.csv')
>>> prices = read_prices('/home/labex/project/prices.csv')
>>> report = make_report(portfolio, prices)
>>> for r in report:
        print(r)

('AA', 100, 9.22, -22.980000000000004)
('IBM', 50, 106.28, 15.180000000000007)
('CAT', 150, 35.46, -47.98)
('MSFT', 200, 20.89, -30.339999999999996)
('GE', 95, 13.48, -26.889999999999997)
...
>>>
✨ 解答を確認して練習

演習2.10:フォーマット済みの表の出力

演習2.9のforループをやり直しますが、print文を変更してタプルをフォーマットします。

>>> for r in report:
        print('%10s %10d %10.2f %10.2f' % r)

          AA        100       9.22     -22.98
         IBM         50     106.28      15.18
         CAT        150      35.46     -47.98
        MSFT        200      20.89     -30.34
...
>>>

また、値を展開してf-文字列を使用することもできます。たとえば:

>>> for name, shares, price, change in report:
        print(f'{name:>10s} {shares:>10d} {price:>10.2f} {change:>10.2f}')

          AA        100       9.22     -22.98
         IBM         50     106.28      15.18
         CAT        150      35.46     -47.98
        MSFT        200      20.89     -30.34
...
>>>

上記の文を取り出して、report.pyプログラムに追加します。プログラムにmake_report()関数の出力を取り込ませ、表示されるように整ったフォーマットの表を出力させます。

✨ 解答を確認して練習

演習2.11:ヘッダーの追加

次のようなヘッダー名のタプルがあったとします。

headers = ('Name', 'Shares', 'Price', 'Change')

上記のヘッダー名のタプルを受け取り、各ヘッダー名が10文字幅のフィールドで右寄せになり、各フィールドが1つの空白で区切られた文字列を作成するコードをプログラムに追加します。

'      Name     Shares      Price      Change'

ヘッダーを受け取り、ヘッダーとその後に続くデータの間の区切り文字列を作成するコードを書きます。この文字列は、各フィールド名の下にたくさんの「-」文字だけです。たとえば:

'---------- ---------- ---------- -----------'

完了したら、プログラムはこの演習の冒頭に示されている表を生成する必要があります。

名前 株数 価格 変動
AA 100 9.22 -22.98
IBM 50 106.28 15.18
CAT 150 35.46 -47.98
MSFT 200 20.89 -30.34
GE 95 13.48 -26.89
MSFT 50 20.89 -44.21
IBM 100 106.28 35.84
✨ 解答を確認して練習

演習2.12:フォーマットのチャレンジ

価格に通貨記号($)を含め、出力が次のようになるようにコードをどのように修正すればよいでしょうか。

名前 株数 価格 変動
AA 100 $9.22 -22.98
IBM 50 $106.28 15.18
CAT 150 $35.46 -47.98
MSFT 200 $20.89 -30.34
GE 95 $13.48 -26.89
MSFT 50 $20.89 -44.21
IBM 100 $106.28 35.84
✨ 解答を確認して練習

まとめ

おめでとうございます!あなたはフォーマットの実験を完了しました。あなたのスキルを向上させるために、LabExでさらに実験を行って練習してください。