search
LoginSignup
218

posted at

updated at

PythonでExcel作った

はじめに

データサイエンスで誰もがまず間違いなく扱うであろうテーブルデータ。pandasや最近ではpolarsを使って解析・可視化する人も多いでしょう。一方で、データサイズがそれほど大きくないときは、インタラクティブに編集・プロットしたり、セルの中でちゃちゃっと平均とかを計算できるExcelの方が便利な場合が多いです。

pandasGUIというものもあるのですが、かなり操作性が悪いし、開発もそんなホットではないですね...

テーブルデータをExcelみたくいじりながら、いつでもDataFrameでデータを回収してPythonで解析できるソフトがあったらいいなあと思ったので、tabulousというのを作りました。この記事ではこれを簡単に紹介したいと思います。

名前はtabularとfabulousを掛けたものです。GUIはQtで作っています。

なお、詳しいドキュメント(英語)はこちらにあります。

tabulousの特徴

  • Excelで編集 → 保存 → pd.read_csvやその逆はもう絶対にやりたくない。スプレッドシートとJupyter QtConsoleを同時に開いて、シートの編集とPythonでの解析を素早く行き来できるようにした。
  • Excelのxlsx重視とか勝手に日付に直してくるとかそういう変な機能全部なくした。
  • VSCodeのコマンドパレット便利すぎる。実装した。
  • Undo/redo (Ctrl+Z/Ctrl+Y) はすごく大変だけど、大事なので頑張って実装した。
  • プロットはmatplotlibと同じくできる一方で、インタラクティブにも動かせるようにした。
  • カラムごとのデータ型があり、編集時に型チェックが入るTable型と、いわゆるスプレッドシートみたく自由に編集できるSpreadSheet型を用意した。
  • 拡張・流用が簡単にできるようにした。自作Qtウィジェットをビューアーに追加することも、ビューアーやテーブルを自作Qtウィジェットに追加することも可能。

インストール

pipでインストールできます。

$ pip install tabulous[all]

seabornscikit-learnとか、少し重めなのが必要なかったら、PyQtのバージョンだけ指定してインストールしてください。最低限のものだけインストールされます。

$ pip install tabulous[pyqt5]  # こっちの方が多分安定
$ pip install tabulous[pyqt6]

tabulousコマンドでビューアーを起動します。

$ tabulous

もしくはPythonを起動して、TableViewerオブジェクトを作成すると起動します。

$ python
Python 3.9.7 (...いろんな情報)
>>> from tabulous import TableViewer
>>> viewer = TableViewer()

Ctrl+Nを押すと新しいスプレッドシートが追加されます。

image.png

このスプレッドシートはExcelみたく編集できます。

基本操作

以下、MacではCtrlを⌘など、適宜読み替えてください。

  1. QtConsoleの起動
  2. テーブルの追加/取得
  3. 並び替え・フィルター
  4. コマンドパレット
  5. カラーマップ
  6. セル内での計算
  7. プロットの編集

1. QtConsoleの起動

Ctrl+Shift+Cを押すか、上のツールバーの"Home"ツールの">_"みたいなボタンを押すと、下部にQtConsoleウィジェットが追加されます。もう一度押すと隠れます。基本的にここでPythonを対話形式で動かします。

image.png

なお、ビューアー自体はviewerという変数名で名前空間に追加されています。このviewerを使ってプログラム的にビューアー自体を操作していくことになります。

2. テーブルの追加/取得

ファイルを開く場合は、Ctrl+OTableとして、Ctrl+KCtrl+OSpreadSheetとして開きます。

一方、プログラム的には、pd.DataFrameに渡せるものであればadd_spreadsheet関数で追加できます。

viewer.add_spreadsheet({"a": [1, 2, 3]})

テーブルは全てviewer.tablesというlistみたいなものに格納されています。テーブルやその内部のpd.DataFrameは次のように取得できます。

table = viewer.tables[i]  # i番目のテーブルを取得
df = table.data  # テーブルデータをpd.DataFrameで取得

なお、現在アクティブなテーブルはviewer.current_tableで取得可能です。

3. 並び替え・フィルター

テーブルデータの基本ですね。並び替え/フィルターはカラムを右クリックして"Sort"や"Filter"をクリックすればできます。

並び替え

GUIではカラムを右クリックして"Sort"をクリックすればできます。

メディア1-output.gif

プログラム的には例えば次のようにやります。

table.proxy.sort("A")
table.proxy.sort("A", ascending=False)
フィルター

GUIではカラムを右クリックして"Filter"をクリックすればできます。

filter-output.gif

プログラム的には例えば次のようにやります。

table.proxy.filter("C == 'x'")
table.proxy.filter("A % 2 == 0")
並び替え・フィルター中のセルの編集

できますよ~。

edit-output.gif

4. コマンドパレット

「この操作がしたいけどどこにあるの...?」みたいな問題も、コマンドパレットがあればほとんど起きないですよね。コマンドパレットはCtrl+Shift+PもしくはF1で起動します。

下の例は、散布図 → 集計 → 列の挿入 をコマンドパレットで実行したものです。

palette-output.gif

5. カラーマップ

GUIでは、カラムを右クリックしてテキスト・背景にカラーマップを設定できます。

colormap-output.gif

プログラム的には、様々な方法があるので、ドキュメントを参考にしてください。

6. セル内での計算

Excelでの=SUM(A1:A5)みたいのものも(かなり頑張って)実装しました。nppdが名前空間に存在し、さらにテーブルデータがdfに渡されます。Excelみたく、選択領域に基づいて式が更新されます。

eval-output.gif

Excelと異なる点として、"="でスタートする場合は参照を残さず(参照元のセルの値が変わっても更新されない)、"&="でスタートする場合に参照を残すようにしています。これは、セルの値から何度も計算する操作はプログラム的に行う場合が多いので、GUI上では想定外の値の更新を防ごうと考えたためです。
(ただ、正直一般的な需要としてどうなのか分からないので、今後Excelみたいに"="で統一する可能性もありますね...)

7. プロットの編集

インタラクティブに拡大縮小・平行移動できる以外に、ダブルクリックでプロットした要素を編集できます。

plot-output.gif

個人的な好みで実装した機能

1. セルのラベル

セルの上に「平均」とかラベルするのマジで嫌い。"F2"でセル編集モードに入るみたく、"F3"でラベルを編集できるようにしました。ラベルはデータには含まれません。

label-output.gif

2. 様々なコピー・ペースト

Markdown、sphinx、Notion、HTML、あとはnumpyのprintの結果などを直接やりとりできたら何かと便利だと思い、実装しました。

copy-output.gif

ドキュメントを作成するのに早速使えました。

最後に

一応scipyscikit-learnを活用した機能も実装したのですが、長くなるのでとりあえずここまで。
tabulousをよろしくお願いいたします~!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
218