2012-08-07 76 views
1

我正在導入帶有numpy.genfromtxt的CSV文件。Python:numpy.genfromtxt - 需要包含無效字符的列名稱

要導入的數據具有列名稱的標題,其中一些列名稱包含genfromtxt認爲無效的字符。具體而言,一些名稱包含「#」和「」。輸入數據無法更改,因爲它是由我無法控制的其他來源生成的。

使用names=Truecomments=None,我無法引入所需的所有列名稱。

我試過覆蓋numpy.lib.NameValidator.deletechars=None,但這並不影響實際使用的NameValidator類實例。

據我所知,deletechars存在,因爲重新陣列可能訪問字段,就好像它是一個屬性。但是,我只需要能夠讀取包含無效字符的列名稱,即使在讀入時字符被剝離。

是否有辦法強制NameValidator不檢查無效字符或修改它檢查的字符?我無法修改numpy/lib/_iotools.py,因爲我不是root用戶,並且修改共享安裝會很糟糕。

+1

難道你不能自己提取標題,然後跳過它來純粹由'genfromtxt'提取數據嗎? – 2012-08-07 06:32:22

+0

@JakobS。 - 我正在試驗,閱讀標題行,然後使用正則表達式來查找哪些名稱包含無效字符並將其替換。然而,這對我來說並不是一個同質的解決方案,我希望numpy有一條規定可以繞過NameValidator或者至少重新定義刪除者。 – freakinschweet 2012-08-07 06:48:18

+0

嗨,雖然我根據我對問題的最佳猜測給出了一個答案,但如果您給出了一個簡化但完整的csv文件示例,它可能會有所幫助。 – xubuntix 2012-08-07 08:30:26

回答

2

你沒有明確說明numpy.genfromtxt是一個硬性要求,所以讓我建議你試試asciitable

該模塊的方式解析之前更換某些條目:http://cxc.harvard.edu/contrib/asciitable/#replace-bad-or-missing-values

而且你還可以根據現有的定義自己的讀者:http://cxc.harvard.edu/contrib/asciitable/#advanced-table-reading

ASCII表讀取器的輸出是numpy的陣列,所以你應該能夠用asciitable直接替換你當前使用的函數。

1

NameValidator將使用其默認設置爲deletechars如果構建與deletechars=None,但如果您通過非None設置然後它將使用它。並np.genfromtext需要deletechars參數,它傳遞到NameValidator

所以,你應該能夠編寫

np.genfromtxt(..., deletechars=set()) 

爲空集,或默認set("""[email protected]#$%^&*()-=+~\|]}[{';: /?.>,<""")的某個子集:

deletechars = np.lib._iotools.NameValidator.defaultdeletechars - set("# ") 
np.genfromtxt(..., deletechars=deletechars) 
1

恕我直言,genfromtxt通常在情況下,使用一些簡單的解決方案會做。因此,除非你有一些麻煩的數據集(缺少條目,多個未知列類型),否則最好編寫一個快速而髒的解析器(即,跳過一些行,解析頭,讀剩下的部分並重新組織結束)。

現在,如果你真的需要genfromtxt,@ecatmur理直氣壯地指出那的genfromtxtdeletechars參數發送到_iotools.NameValidator來構建一套要刪除的字符。使用deletechars=None告訴NameValidator使用默認設置。首先要嘗試的是不使用deletechars=None,而是使用空的set''

需要注意的是不論怎樣,雙引號"和結束空間將被刪除,類似的名稱將有所區別:會導致命名blah分三路

>>> fields = ["blah", "'blah'", "\"blah\"", "#blah", "blah "] 
>>> np.lib._iotools.NameValidator(deletechars='').validate(fields) 
... ('blah', "'blah'", 'blah_1', '#blah', 'blah_2') 

第三和最後一個條目,所以我們要重命名它們。

如果這不適合你,我恐怕你打了一個塊:目前沒有辦法告訴genfromtxt接受定製的NameValidator。不過,這可能是一個好主意,所以你可能想在numpy的郵件列表上提出點。

+0

這裏有很多好處。 – freakinschweet 2012-08-07 13:39:45

+0

@xubuntix - 我會檢查我的安裝,看看是否可用。不幸的是,在我的工作環境中,添加新模塊的過程非常困難。 @ecatmur @Pierre GM - 我也嘗試過'genfromtxt'中的'deletechars = set()',但NameValidator類只是執行'set.extend(「」「〜!@#$%^&*() - =你可以想象,設置'deletechars ='''會產生一個ValueError,因爲沒有string.extend()。 ) 方法。此外,嘗試修改'np.lib._iotools'將不起作用,因爲'genfromtxt'會創建一個新實例。 謝謝大家的幫助! – freakinschweet 2012-08-07 13:51:12

+0

@ user1580983作爲一種快速解決方案:使用'np.genfromtxt'代碼創建自己的函數,然後擺脫'NameValidator'。這不會是可移植的,但會讓你繼續前進。我會建議在numpy郵件列表上發佈這個問題,並最終打開一張票。 – 2012-08-07 14:08:57