Python Pandas loc create fortran ordered numpy数组

2024-03-28 19:44:38 发布

您现在位置:Python中文网/ 问答频道 /正文

例如:

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数组创建pandas数据帧?我可以强制它用C命令的numpy数组创建pandas数据帧吗?在


Tags: numpypandasnp数组loclistixvalues
2条回答

无法回答您的第一个问题,但在数据帧上调用.values将返回numpy ndarray,因此:

希望有帮助!在

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

索引问题会创建一个F有序数组,如flagsstrides中所示。这是我在普通numpy数组上执行transpose时看到的。在

^{pr2}$

但其他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索引器中的一个bug。在

我猜np.ascontiguousarray是确保所有case都是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)

相关问题 更多 >