你如何在 pandas 或 numpy 中切片横截面?

How do you slice a cross section in pandas or numpy?

我有以下数据框,它可以是 copy/pasted 并制作成一个数据框:df = pd.read_clipboard()

    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
0    0   1   5  12  13   7   1   5   5   1   7  13  12   5   1   0
1    1   0   4  13  12   6   0   4   4   0   6  12  13   4   0   1
2    5   4   0   9   8   2   4   0   0   4   2   8   9   0   4   5
3   12  13   9   0   1  11  13   9   9  13  11   1   0   9  13  12
4   13  12   8   1   0  10  12   8   8  12  10   0   1   8  12  13
5    7   6   2  11  10   0   6   2   2   6   0  10  11   2   6   7
6    1   0   4  13  12   6   0   4   4   0   6  12  13   4   0   1
7    5   4   0   9   8   2   4   0   0   4   2   8   9   0   4   5
8    5   4   0   9   8   2   4   0   0   4   2   8   9   0   4   5
9    1   0   4  13  12   6   0   4   4   0   6  12  13   4   0   1
10   7   6   2  11  10   0   6   2   2   6   0  10  11   2   6   7
11  13  12   8   1   0  10  12   8   8  12  10   0   1   8  12  13
12  12  13   9   0   1  11  13   9   9  13  11   1   0   9  13  12
13   5   4   0   9   8   2   4   0   0   4   2   8   9   0   4   5
14   1   0   4  13  12   6   0   4   4   0   6  12  13   4   0   1
15   0   1   5  12  13   7   1   5   5   1   7  13  12   5   1   0

我想从中截取一个横截面,我想要这样的东西:

[1, 4, 9, 1, 10, 6, 4, 0, 4, 6, 10, 1, 9, 4, 1])

这是索引 df.loc[1, 0], df.loc[2, 1], df.loc[3, 2], df.loc[4, 3 ],等等

是否有 numpy 或 pandas 模式比我正在做的许多不同的索引更容易获得这种类型的交叉切片?谢谢

我用numpy来解决这个问题。

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(16 * 16).reshape(16, 16))
print(df)

print(df.to_numpy()[range(15), range(1, 16)])

你可以使用 numpy advanced indexing:

例如,如果您想 select

df.loc[1, 0], df.loc[2, 1], df.loc[3, 2], df.loc[4, 3]

首先将 df 转换为 numpy 数组,然后使用适当的行和列索引对元素进行索引:

df_to_arr = df.to_numpy()
out = df_to_arr[[1,2,3,4], [0,1,2,3]]

输出:

array([1, 4, 9, 1], dtype=int64)

我们可以使用 np.diagonaloffset=1 到 select 主对角线上方的对角线元素

np.diagonal(df, offset=1)

array([ 1,  4,  9,  1, 10,  6,  4,  0,  4,  6, 10,  1,  9,  4,  1])

如果你有一个numpy数组,你实际上可以得到一个切片。切片和高级索引表达式之间的区别在于,切片 returns 是原始数据的视图,而高级索引总是制作副本。如果数组是C-contiguous,可以用ravel得到视图:

arr = df.to_numpy()

row = 1
col = 0
n = 4
view = arr.ravel()[row * arr.shape[1] + col:(row + n - 1) * arr.shape[1] + col + n:arr.shape[1] + 1]

如果您没有连续数组,则需要多做一些工作,因为您需要手动设置视图的步幅。您可以使用 np.lib.stride_tricks.as_strided:

view = np.lib.stride_tricks.as_strided(arr[row:, col:], shape=n, strides=arr.strides[0] + arr.strides[1])

这应该与 中介绍的更简单的方法相同。