2013-02-18 72 views
3

[此文章的早期版本的標題不準確「如何將一列添加到numpy記錄數組?」問題在早期標題已部分answered,但這個答案不是什麼機構這個帖子的早期版本所要求的。我重寫了這個標題,並且對這個帖子進行了大量編輯,以使區分更加清晰。我也解釋了爲什麼我剛纔提到的答案達不到的東西我要找的。]如何堆疊numpy記錄的數組?


假設我有兩個numpy陣列xy,每組[R「記錄」(又名「結構化「)陣列。讓的x形狀是(- [RÇ X)和y形狀是(- [RÇý)。我們還假設x.dtype.namesy.dtype.names之間沒有重疊。

例如,對於- [R = 2,Ç X = 2,並且ÇŶ = 1:

import numpy as np 
x = np.array(zip((1, 2), (3., 4.)), dtype=[('i', 'i4'), ('f', 'f4')]) 
y = np.array(zip(('a', 'b')), dtype=[('s', 'a10')]) 

我想 「水平」 串聯xy產生記錄數組z,形狀(r,c x + c y)。此操作根本不應修改xy

一般來說,z = np.hstack((x, y))不會做,因爲dtype的在xy不一定匹配。例如,繼續上面的例子:

z = np.hstack((x, y)) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-7-def477e6c8bf> in <module>() 
----> 1 z = np.hstack((x, y)) 
TypeError: invalid type promotion 


現在,有一個功能,numpy.lib.recfunctions.append_fields,那看起來像它可能做一些接近我正在尋找,但我沒有能夠從中得到任何東西:我嘗試過的所有事情要麼是失敗,要麼是產生的東西不是我想要得到的東西。

可有人請告訴我明確在上面的例子中定義的代碼(使用n.l.r.append_fields或以其他方式),這將產生,從xy,一個陣列的記錄,z,相當於xy的橫向級聯,並且在不修改xy的情況下這樣做?

我認爲這隻需要一行或兩行代碼。當然,我正在尋找不需要建築物z的代碼,通過記錄來迭代xy。此外,代碼可以假定xy具有相同的記錄數,並且在x.dtype.namesy.dtype.names之間沒有重疊。除此之外,我正在尋找的代碼應該對xy一無所知。理想情況下,它也應該是不可知論的數組加入。 IOW,遺漏了錯誤檢查,我正在尋找的代碼可能是函數的主體hstack_rec,因此新陣列z將會是結果hstack_rec((x, y))


...雖然我不得不承認,在我與numpy.lib.recfunctions.append_fields失敗迄今爲止在完美的紀錄,我已經變得有點好奇如何此功能可用於在全部,不管它與這個職位的問題的相關性。

+0

'當d = np.array([3.2],D型細胞= np.double) Z = rf.append_fields(X ,'field4',data = [d],dtypes = [np.double],usemask = False)' – 2013-10-16 18:24:10

回答

4

我從來不使用recarrays,所以別人會想出一些東西,但也許merge_arrays會工作?

>>> import numpy.lib.recfunctions as nlr 
>>> x = np.array(zip((1, 2), (3., 4.)), dtype=[('i', 'i4'), ('f', 'f4')]) 
>>> y = np.array(zip(('a', 'b')), dtype=[('s', 'a10')]) 
>>> x 
array([(1, 3.0), (2, 4.0)], 
     dtype=[('i', '<i4'), ('f', '<f4')]) 
>>> y 
array([('a',), ('b',)], 
     dtype=[('s', '|S10')]) 
>>> z = nlr.merge_arrays([x, y], flatten=True) 
>>> z 
array([(1, 3.0, 'a'), (2, 4.0, 'b')], 
     dtype=[('i', '<i4'), ('f', '<f4'), ('s', '|S10')]) 
+0

值得注意的是,儘管'recfunctions'被這樣命名,merge_arrays也適用於結構化數組,陣列!一個驚喜。 – mach 2018-02-24 02:15:55

0

這是一個很晚的答案,但也許會對別人有所幫助。在用相同的標準提出同樣的問題之後,我使用了這個解決方案。

它不會生成一個新的numpy數組,但通過使用zipitertools.chain它會快得多。就我而言,我需要按順序訪問每一行的每個值。下面是基準,這模擬了這種用例:

import numpy 
from numpy.lib.recfunctions import merge_arrays 
from itertools import chain 

a = numpy.empty(3, [("col1", int), ("col2", float)]) 
b = numpy.empty(3, [("col3", int), ("col4", "U1")]) 

結果:

%timeit [i for i in (row for row in merge_arrays([a,b], flatten=True))] 
52.9 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

%timeit [i for i in (row for row in (chain(i,k) for i,k in zip(a,b)))] 
3.47 µs ± 52 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)