2017-09-15 45 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)