2017-09-15 44 views
2

例如:Python的大熊貓 - 祿創建FORTRAN有序numpy的陣列

nrow = 10 
ncol= 10 
a = np.arange(nrow*ncol,dtype=np.int32).reshape(nrow,ncol) 
a = pd.DataFrame(a) 
ix_list = np.arange(nrow,dtype=np.int32) 

print np.isfortran(a.values) # False 
print np.isfortran(a.loc[ix_list,:].values) # True 

爲什麼創建的.loc大熊貓據幀與FORTRAN有序numpy的陣列?我可以強制它創建與C有序numpy數組的熊貓數據框?

+0

這是什麼'loc'產生陣列的'shape'?它的「旗幟」? – hpaulj

+0

你的意思是從a.loc [ix_list ,:]中ndarray的形狀?它與a的形狀相同,在這種情況下是(10,10)。 –

回答

0

不能回答你的第一個問題,但你的數據幀調用.values會返回一個numpy的ndarray這樣:

^h操作它有幫助!

+0

非常感謝。我正在尋找一種迫使.loc直接爲性能問題創建C命令的ndarray。 np.ascontiguousarray()在與fortran命令的更大尺寸一起使用時很慢。 –

+0

好的,你能分享你的發現嗎? –

+0

對不起,我的意思是我找不到這樣的方式。 –

0
In [423]: adf = pd.DataFrame(a) 
In [424]: ix_list = np.arange(nrow,dtype=np.int32) 

您的問題索引創建A F有序排列,如flagsstrides看到。這是我期望在普通numpy陣列上做transpose時看到的結果。

In [426]: adf.loc[ix_list].values.flags 
    Out[426]: 
     C_CONTIGUOUS : False 
     F_CONTIGUOUS : True 
     OWNDATA : False 
     WRITEABLE : True 
     ALIGNED : True 
     UPDATEIFCOPY : False 
    In [427]: adf.loc[ix_list].values.strides 
    Out[427]: (4, 40) 

但其他loc索引產生一個C順序排列:

In [428]: adf.loc[:].values.flags 
Out[428]: 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    .... 
In [429]: adf.loc[ix_list[::2]].values.flags 
Out[429]: 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    ... 
In [430]: adf.loc[ix_list[:-2]].values.flags 
Out[430]: 
    C_CONTIGUOUS : True 
    F_CONTIGUOUS : False 
    ... 

這看起來在pandasloc索引的錯誤。

我猜np.ascontiguousarray是最便宜的方法來確保所有的情況下都是C排序的,因爲它有一個np.array(..., copy=False),這是一個條件copy。已經是C的數組將不會複製。

在快速測試中,增加一個copynp.ascontiguousarray並不會減慢速度。

In [439]: timeit np.ascontiguousarray(adf.loc[ix_list].values).flags 
514 µs ± 7.07 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
In [440]: timeit adf.loc[ix_list].values.copy().flags 
509 µs ± 5.94 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
In [441]: timeit adf.loc[ix_list].values.flags 
513 µs ± 18.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
In [442]: timeit adf.loc[:].values.flags 
24.9 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
In [443]: timeit np.ascontiguousarray(adf.loc[:].values).flags 
30 µs ± 865 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
In [444]: timeit adf.loc[ix_list[:-1]].values.flags 
559 µs ± 12.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
In [445]: timeit np.ascontiguousarray(adf.loc[ix_list[:-1]].values).flags 
559 µs ± 1.41 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 

的numpy的陣列上選擇行是大大高於使用loc

In [446]: timeit adf.loc[:].values[ix_list].flags 
32.9 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 
In [447]: timeit adf.values[ix_list].flags 
20.9 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)