你如何在 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.diagonal
和 offset=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])
这应该与 中介绍的更简单的方法相同。
我有以下数据框,它可以是 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.diagonal
和 offset=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])
这应该与