<pre><code>In [423]: adf = pd.DataFrame(a)
In [424]: ix_list = np.arange(nrow,dtype=np.int32)
</code></pre>
<p>索引问题会创建一个F有序数组,如<code>flags</code>和<code>strides</code>中所示。这是我在普通numpy数组上执行<code>transpose</code>时看到的。在</p>
^{pr2}$
<p>但其他<code>loc</code>索引生成一个C顺序数组:</p>
<pre><code>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
...
</code></pre>
<p>这看起来是<code>pandas</code><code>loc</code>索引器中的一个bug。在</p>
<p>我猜<code>np.ascontiguousarray</code>是确保所有case都是C序的最便宜的方法,因为它执行<code>np.array(..., copy=False)</code>,这是一个条件<code>copy</code>。已经是<code>C</code>的数组将不会生成副本。在</p>
<p>在快速测试中,添加<code>copy</code>或<code>np.ascontiguousarray</code>并不会减慢速度。在</p>
<pre><code>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)
</code></pre>
<p>在numpy数组上选择行比使用<code>loc</code>快得多:</p>
<pre><code>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)
</code></pre>