簡體   English   中英

在 Python 中將文本表轉換為 CSV

[英]Converting Text Tables Into CSVs in Python

我希望將表格數據轉換為 CSV,但是當表中的行具有某些缺失值時,我遇到了障礙。 輸入如下表所示,

systemd       1                   root  cwd       DIR                8|1      4096          2 /
systemd       1                   root  rtd       DIR                8|1      4096          2 /
systemd       1                   root  txt       REG                8|1   1612152     101375 /lib/systemd/systemd
systemd       1                   root  mem       REG                8|1   1700792      26009 /lib/x86_64-linux-gnu/libm-2.27.so
systemd       1                   root  mem       REG                8|1    121016       1715 /lib/x86_64-linux-gnu/libudev.so.1.6.9
node        697   698             user1 cwd       DIR               8|33      4096    7995393 /home/user1
node        697   698             user2 rtd       DIR                8|1      4096          2 /
node        697   698             user1 txt       REG               8|33  43680144    8003081 /home/user1/.vscode-server/bin/26076a4de974ead31f97692a0d32f90d735645c0/node
node        697   698             user1 mem       REG                8|1    101168      26021 /lib/x86_64-linux-gnu/libresolv-2.27.so
node        697   698             user1 mem       REG                8|1     26936      26014 /lib/x86_64-linux-gnu/libnss_dns-2.27.so

我想將其轉換為保留列數的 CSV,輸出應如下所示,

systemd,1,,root,cwd,DIR,8|1,4096,2,/
systemd,1,,root,rtd,DIR,8|1,4096,2,/
systemd,1,,root,txt,REG,8|1,1612152,101375,/lib/systemd/systemd
systemd,1,,root,mem,REG,8|1,1700792,26009,/lib/x86_64-linux-gnu/libm-2.27.so
systemd,1,,root,mem,REG,8|1,121016,1715,/lib/x86_64-linux-gnu/libudev.so.1.6.9
node,697,698,user1,cwd,DIR,8|33,4096,7995393,/home/user1
node,697,698,user2,rtd,DIR,8|1,4096,2,/
node,697,698,user1,txt,REG,8|33,43680144,8003081,/home/user1/.vscode-server/bin/26076a4de974ead31f97692a0d32f90d735645c0/node
node,697,698,user1,mem,REG,8|1,101168,26021,/lib/x86_64-linux-gnu/libresolv-2.27.so
node,697,698,user1,mem,REG ,8|1,26936,2601,/lib/x86_64-linux-gnu/libnss_dns-2.27.so

到目前為止,我已經嘗試使用 pandas read_fwf 函數然后將其轉換為 CSV,但它沒有評估缺失的列值。 因此,我沒有為 CSV 中的每一行獲取 10 個值,而是只獲取可見的 9 個值。使用 Pandas read_table 函數時也會發生同樣的事情。 我也嘗試使用 Regex Patterns,但我不希望表格格式每次都相同,升級代碼以合並更多表格成為一個問題

任何解決此問題的方法都受到高度贊賞。 非常感謝!

您可以通過將數據拆分為有效行和無效行來縮小問題。 有效行將具有預期的列數,而無效行將缺少一列或多列。 不確定您是否可以在不知道列之間的確切分隔符的情況下完全自動化。

您提到描述列中可以出現空格。 您無法真正區分user1 cwd是兩個單獨的列和一個列內的空格。 這樣的行將被放入invalid列表中,除非它們碰巧有一個缺失值來“平衡”它。 它非常脆弱,因此最好確保您有一個正確的分隔符,或者至少您的列值中沒有空格。

from io import StringIO
import pandas as pd
import re

data = StringIO("""
systemd       1                   root  cwd       DIR                8|1      4096          2 /
systemd       1                   root  rtd       DIR                8|1      4096          2 /
systemd       1                   root  txt       REG                8|1   1612152     101375 /lib/systemd/systemd
systemd       1                   root  mem       REG                8|1   1700792      26009 /lib/x86_64-linux-gnu/libm-2.27.so
systemd       1                   root  mem       REG                8|1    121016       1715 /lib/x86_64-linux-gnu/libudev.so.1.6.9
node        697   698             user1 cwd       DIR               8|33      4096    7995393 /home/user1
node        697   698             user2 rtd       DIR                8|1      4096          2 /
node        697   698             user1 txt       REG               8|33  43680144    8003081 /home/user1/.vscode-server/bin/26076a4de974ead31f97692a0d32f90d735645c0/node
node        697   698             user1 mem       REG                8|1    101168      26021 /lib/x86_64-linux-gnu/libresolv-2.27.so
node        697   698             user1 mem       REG                8|1     26936      26014 /lib/x86_64-linux-gnu/libnss_dns-2.27.so
""")

valid_rows = []
invalid_rows = []
num_of_columns = 10

for line in data.readlines():
    # note that in your data there is a new line
    # at the end of each line which is also captured by \s
    if len(re.findall(r"\s+", line)) == num_of_columns:
        valid_rows.append(line)
    else:
        invalid_rows.append(line)        

df = pd.read_csv(StringIO("".join(valid_rows)), delim_whitespace=True, names=range(10))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM