2025年12月6日 星期六

visidata: 終端機下的輕薄短小試算表

visidata 整理台股財報摘要 大推! 文字視窗底下的試算表軟體 visidata 超級輕薄短小, 我已使用好幾個月了, 雖然還不是很熟, 但已足以處理大部分簡單的工作。 習慣 vim 按鍵的人, 會很容易上手。 它可以處理 csv、 ods、 xlsx、 ... 等等 許多格式。 我偶爾拿它來處理 json, 不過大部分時候還是處理 csv 檔。 你可以在 visidata 裡面寫 python 運算式計算新欄位, 但無法儲存公式, 只能儲存運算結果, 適合做一些簡單、 用丟即棄的運算。

請下載 25Q3.csv (台股上市櫃公司 2025 年第三季財報摘要) 及 price.csv (台股上市櫃公司昨天或今天收盤價), 我拿這兩個檔案來幫大家導覽一下 visidata 的簡單使用。 請先用文字編輯器 (例如 vim 或 geany) 打開這兩個檔案檢視一下內容, 或是下 head 25Q3.csv 檢視。 在 debian 系列的 linux 上, 用 sudo apt install visidata 指令安裝 visidata, 然後下 visidata 25Q3.csv 開啟試算表。 因為它是 python 寫的, 所以 也有 windows、 MacOS 等等版本 喔!

一、 基本操作

  1. hjkl、 方向鍵: 移動 cursor (就是反白那一列跟粗體那一行的交叉位置)。
  2. HL : 把目前這一欄向左、向右移。
  3. JK : 把目前這一列向下、向上移。
  4. e edit: 進入編輯模式, 修改 cursor (游標) 所在這一格的值。 亂改一氣, 按 enter 結束編輯模式, 回到移動模式。 不用擔心改壞掉, 因為...
  5. U undo: 取消前一個動作。
  6. R redo: 取消之後的反悔。
  7. d delete: 刪除游標所在這一列 (目前這一列)。
  8. a append: 在目前這一列後面新增一空列。
  9. y yank: 把目前這一列複製到暫存區。 (試算表看不出任何改變) (yank)
  10. p put/paste: 把暫存區內的資料貼到目前這一列之後。
  11. s select: 把目前這一列加入選取範圍。 (移動一下, 隨便多選幾列。) 已加入選取範圍的列會變色、 前面有一個點。
  12. u unselect: 把目前這一列從選取範圍中移除。
  13. t toggle:目前這一列, 若未選取則選取它; 若已選取則改成不選。
  14. ^g: (control + g) 檢視編輯器目前狀態。 右下方會顯示游標目前位於第幾列、 現在已選取幾列。 也請注意最右下角顯示的總列數。
  15. gd: (先按 g, 再按 d, 意思是 globally delete) 刪除所有已加入選取範圍的列。 注意最右下角顯示的總列數變化。
  16. U: 取消前一個動作。

請再胡亂編輯一下檔案, 把它搞亂掉, 例如在好幾處按 s 選取幾列、 按 gy 複製這幾列、 移動到遙遠的位置, 再按 p 貼上剛剛複製的那幾列。 是不是很像 vim 呢? 習慣用 y 的讀者會發現一個差別: 在 vim 裡面, delete 的同時就有複製的效果, 所以 ddp 會把這一列跟下一列交換; 但是在 visidata 裡面, 要按 ydp

然後按 q 離開。 它不會詢問, 會直接丟棄所有的更動! 再次進入 visidata, 會看到資料檔沒有變動。 如果要存檔, 必須按 ^s (control + s)。 以下請不時按 ^s 儲存辛苦編輯的結果。

編輯半天, 萬一忘記存檔直接跳離怎麼辦? 當初若在命令列上加上 --quitguard 選項, 就不會有這樣的悲劇。 有此選項, 當你要離開時, 它便會詢問確認 (但不會自動幫你存檔!) 此時你可以按 yes 確認「不存檔直接結束」, 或是按 no 繼續編輯、 按 ^s 存檔、 再按 q 離開。

也可以建立 ~/.visidatarc 設定檔, 在裡面填入一句: options.quitguard=True 就等同於每次都下這個選項。

二、 實作: 看財報海撈股票

巴菲特挑股票的第一重點 是具有 (長期的) 較高 ROE。 好的, 那我們就以試算表的 ROE 那一欄來排序。 把游標移到 「ROE」 那一欄, 然後按 [ 好像變成由小排到大, 但又不太像... 再按 ] 應該是由大排到小, 但是...?

把游標移到最左邊 「代號」 那一欄、 按 / 代表 "搜尋"、 輸入搜尋字串 "2330" 找到台積電、 按 ^g 查看游標目前位置, 結果台積電竟然是七百多名?!

原來是因為 visidata 把所有資料都當成字串在處理。 再把游標移回 「ROE」、 按 % 告訴 visidata 這一欄是浮點數、 ] 重新降冪排序。 再次查看台積電的排名, 39, 這才對嘛! 其他常用的資料型態指定鍵還有: # 整數、 @ 日期、 ~ 字串。

再來, 讓我們刪除過時很久的 「股價」 欄, 以及 (貴哥不懂該如何分析的) 大部分欄位。 按 C (大寫 C, 代表 column) 進入 column sheet, 也就是顯示所有欄位的系統 "分頁"。 原表格的每一 (直) 欄, 在這裡變成一 (橫) 列。 如果想修改欄位名稱, 可以在這裡的最左欄適當的位置按 e。 按幾次 d, 刪掉大部分欄位, 只保留代號、 ROE、 ROA、 EPS、 BPS 等五個欄位。 按 q 離開 column sheet、 回到資料分頁。 把 「代號」 以外、 剩下的每個欄位都指定成浮點數。

只想保留賺錢能力強的股票。 按 z 再按 |, 表示要下搜尋條件。 下方出現 "select by expr" 提示。 輸入 ROE>=15, 看到右下角狀態列顯示已選擇一百八十幾筆。 按 g 再按 t, 翻轉所有列的 「是否已選擇」 狀態。 按 g 再按 d, 刪除所有 ROE 不到 15 的列。

想要驗證這個公式: ROE 大約等於 EPS/BPS。 (請見: 程式設計老手的股市初學淺見) 把游標移到最右邊那一欄。 按 =, 表示要寫數學式建立新欄位。 下方出現 "new column expr=" 提示。 輸入 EPS/BPS*100/ROE, 按 enter。 右側出現新的欄位。 按 [] 排序一下, 嗯, 果然大部分的數值落在 0.9 到 1.1 之間。 按 % , 指定這一欄為浮點數。

進入 column sheet, 把新欄位的名稱改為「驗算」, 欄位寬度改為 7。

三、 join/vlookup() 合併兩張試算表

再來要幫股票補上中文名稱。 以資料庫的術語來說, 就是要做 join; 以 LibreOffice calc 或 google sheet 或 MS excel 來說, 就是要做 vlookup()。

  1. o 表示要讀取檔案。 輸入 price.csv 的路徑。 畫面變成另一張試算表 (開啟了一個新的分頁), 有代號、名稱、收盤價三個欄位。
  2. % 把 「收盤價」 那一欄設定為浮點數。 再把游標移到 「代號」 那一欄, 按 ! 將它指定為 primary key (主鍵)。
  3. S 切換到 sheet sheet, 也就是顯示所有分頁的系統 "分頁"。 把游標移到 "25Q3" 那一列、 按 enter 切換回財報分頁。
  4. 同樣地, 把游標移到 「代號」 那一欄, 按 ! 將它指定為財報分頁的主鍵。
  5. S 切換到 sheet sheet。 在 "25Q3" 跟 "price" 兩列上面都按 s 納入選取範圍。
  6. JK 調整列的上下順序, 確認 "25Q3" 在上, "price" 在下。
  7. & 表示要 join。 下方出現 "choose jointype:" 提示。 鍵入 "outer"、 按 enter, 表示要以 25Q3 為主, 查詢每一檔股票的名稱及收盤價。 出現了一張新的分頁, 含有一百八十多檔股票的資訊 (來自兩張試算表)。
  8. 再按 = 、 輸入 收盤價/EPS, 建立新的欄位、 按 %
  9. C 切換到 column sheet, 編輯 name 欄位, 把 "收盤價/EPS" 改成 "本益比", 又編輯 width 欄位, 把幾個小數點位數太多的數值欄位的寬度變小。

四、 繪圖

visidata 繪製散點圖 沒錯, visidata 可以在終端機底下繪製散點圖!

  1. 在 「代號」 欄按 ! 取消它主鍵的地位。
  2. 在 「本益比」 欄按 ! 指定它作為 X 軸。
  3. 在 「ROE」 欄按 . 指定它作為 Y 軸。

按下 . 之後, 馬上出現散點圖。 可以用方向鍵把游標移到有興趣的點。 以我們的例子來說, 就是右下角 - 高 ROE、 低本益比。 按下 enter, 即可查看位於該處的個股。

如果有一個 "分類" 性質的文字欄位 (例如每一檔個股屬於 「電/傳/金」 哪種類股、 每一項產品來自哪家供應商、 通識課的每一位學生來自哪個學院、 ...), 也可以在繪圖之前用 ! 指定用它決定點的顏色。 有兩欄都被 ! 指定, visidata 不會混淆嗎? 不會, 因為一個是數值欄, 另一個是字串欄。 但類別不能太多。

但是! 本文並不是投資建議, 這只是一篇軟體操作教學文嘿 :-)

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。