Python Pandas-loc创建fortran有序numpy数组
例如:Python Pandas-loc创建fortran有序numpy数组,python,pandas,numpy,Python,Pandas,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使用fortra
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数组创建pandas数据帧吗?无法回答您的第一个问题,但在数据帧上调用
。值将返回numpy数据帧,因此:
- 要检查数组是否如文档中所述为fortran,最好使用numpy alternative
.flags.f_continuous
()
- 使用
np.ascontiguousarray()
或np.asfortranarray()
希望有帮助
In [423]: adf = pd.DataFrame(a)
In [424]: ix_list = np.arange(nrow,dtype=np.int32)
您的问题索引创建了一个F有序数组,如标志
和步幅
中所示。这就是我在普通numpy数组上执行转置时希望看到的结果
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
...
这在pandas
loc
索引器中看起来是个bug
我猜np.ascontiguousarray
是确保所有案例都是C有序的最便宜的方法,因为它执行np.array(…,copy=False)
,这是一种条件复制。已经是C
的数组不会复制
在快速时间测试中,添加副本
或np.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)
谢谢。我正在寻找一种方法,强迫.loc直接为性能问题创建C命令的ndarray。np.ASCONTIGOUUSARRAY()在与较大大小的fortran命令ndarray一起使用时速度较慢。好的,请分享您的发现好吗?对不起,我的意思是我找不到这样的方法。对不起,我的不好。以防万一,换个数组怎么样?例如使用a.loc[ix_list,:].transpose().值?还有一个问题,为什么需要使用.loc?您是否可以只使用df选择,例如:一个[ix_列表].values这个loc
生成的数组的形状是什么?它的标志
?你是指a.loc[ix_list,:]中的数据阵列的形状吗?它的形状与a相同,在本例中为(10,10)。