2015-12-17 67 views
4

previous posts我看到改變dtyperecarray可以使用astype執行。然而,我無法設法用recarray這個在其中一列中有一個數組的方法。當其中一列是數組時,如何更改numpy recarray的dtype?

recarray來自一個FITS文件記錄:

> f = fits.open('myfile.fits') 
> tbdata = f[1].data 
> tbdata 
# FITS_rec([ (0.27591679999999996, array([570, 576, 566, ..., 571, 571, 569], dtype=int16)), 
# (0.55175680000000005, array([575, 563, 565, ..., 572, 577, 582], dtype=int16)), 
# ..., 
# (2999.2083967999997, array([574, 570, 575, ..., 560, 551, 555], dtype=int16)), 
# (2999.4842367999995, array([575, 583, 578, ..., 559, 565, 568], dtype=int16)], 
# dtype=[('TIME', '>f8'), ('AC', '>i4', (2,))]) 

我需要AC列從int轉換爲float所以我已經試過:

> tbdata = tbdata.astype([('TIME', '>f8'), ('AC', '>f4', (2,))]) 

,雖然看起來dtype確實發生了變化

> tbdata.dtype 
# dtype([('TIME', '>f8'), ('AC', '>f4', (2,))]) 

看一下的數據AC表明它們仍然是整數值。例如,一個計算sum到達int16變量的限制(所有AC列值是陽性的):

> tbdata['AC'][0:55].sum() 
# _VLF(array([31112, 31128, 31164, ..., 31203, 31232, 31262], dtype=int16), dtype=object) 
> tbdata['AC'][0:65].sum() 
# _VLF(array([-28766, -28759, -28702, ..., -28659, -28638, -28583], dtype=int16), dtype=object) 

是否有任何的方式來有效地改變所述陣列的數據類型?

+0

不是答案,只是好奇:根據D型細胞中,「AC」字段是具有形狀的陣列(2)。爲什麼註釋輸出顯示該字段具有更多元素?例如。 'array([570,576,566,...,571,571,569],dtype = int16)' –

+0

我不能重現這一點,但我沒有使用你的FITS庫。我們可以複製並運行一個獨立的示例會很有幫助。不要使用FITS數據;只需「手動」創建一個簡單的dtype和數組即可用於演示問題。 –

+0

@WarrenWeckesser:對於第一個問題,我不確定,但我想這與'AC'字段是一個FITS可變長度數組這一事實有關...... – mtc

回答

0

我可以用適合文件中的recarray來重現此問題。 一種解決方法是加載recarray作爲配合表,然後將其轉變成一個大熊貓數據幀:

from astropy.table import Table 
import pandas as pd 

t = Table.read('file.fits') 
df = pd.DataFrame.from_records(t, columns=t.columns) 
df.AC = df.AC.astype(float) 
+0

非常感謝這個解決方法! – mtc

0

繼沃倫建議,如果我嘗試用「手動」創建recarray,事情似乎進展順利:

> ra = np.array([ ([30000,10000], 1), ([30000,20000],2),([30000,30000],3) ], dtype=[('x', 'int16',2), ('y', int)]) 
> ra 
# array([([30000, 10000], 1), ([30000, 20000], 2), ([30000, 30000], 3)], 
#  dtype=[('x', '<i2', (2,)), ('y', '<i8')]) 
> ra = ra.astype([('x', '<f4', (2,)), ('y', '<i8')]) 
> ra 
# array([([30000.0, 10000.0], 1), ([30000.0, 20000.0], 2), 
#  ([30000.0, 30000.0], 3)], dtype=[('x', '<f4', (2,)), ('y', '<i8')]) 

所以,INT16數轉換爲浮點數。

然而,astype打到我TBDATArecarray後,數字似乎並沒有做任何改動(也沒有內部dtype):

> tbdata.dtype 
# dtype([('TIME', '>f8'), ('AC', '>f4', (2,))]) 
> tbdata 
# FITS_rec([ (0.27591679999999996, array([570, 576, 566, ..., 571, 571, 569], dtype=int16)), 
# (0.55175680000000005, array([575, 563, 565, ..., 572, 577, 582], dtype=int16)), 
# ..., 
# (2999.2083967999997, array([574, 570, 575, ..., 560, 551, 555], dtype=int16)), 
# (2999.4842367999995, array([575, 583, 578, ..., 559, 565, 568], dtype=int16))], 
# dtype=[('TIME', '>f8'), ('ADC', '<f4', (2,))]) 

我的結論是,這可能是相關的問題FITS文件的AstroPy接口。此外,在sum()之後檢索到的負數實際上與數據類型無關,但由於FITS存儲的數字大於32768,所以它們出現在整數數組中間的tbdata中,使用TZERO關鍵字用於無符號整數的偏移量。問題是CFITSIO和普通的FITS查看器以一種透明的方式爲用戶重新轉換這些數字,因此我不知道這些負數。 非常感謝您的幫助和建議。

相關問題