Python 如何同时删除numpy中某些索引处的列和行

Python 如何同时删除numpy中某些索引处的列和行,python,numpy,Python,Numpy,我有这样一个正方形矩阵: [[0, 516, 226, 853, 1008, 1729, 346, 1353, 1554, 827, 226, 853, 1729, 1008], [548, 0, 474, 1292, 1442, 2170, 373, 1801, 1989, 1068, 474, 1292, 2170, 1442], [428, 466, 0, 1103, 1175, 1998, 226, 1561, 1715, 947, 0, 1103, 1998, 1175], [663,

我有这样一个正方形矩阵:

[[0, 516, 226, 853, 1008, 1729, 346, 1353, 1554, 827, 226, 853, 1729, 1008],
[548, 0, 474, 1292, 1442, 2170, 373, 1801, 1989, 1068, 474, 1292, 2170, 1442],
[428, 466, 0, 1103, 1175, 1998, 226, 1561, 1715, 947, 0, 1103, 1998, 1175],
[663, 1119, 753, 0, 350, 1063, 901, 681, 814, 1111, 753, 0, 1063, 350],
[906, 1395, 1003, 292, 0, 822, 1058, 479, 600, 1518, 1003, 292, 822, 0],
[1488, 1994, 1591, 905, 776, 0, 1746, 603, 405, 1676, 1591, 905, 0, 776],
[521, 357, 226, 1095, 1167, 1987, 0, 1552, 1705, 1051, 226, 1095, 1987, 1167],
[1092, 1590, 1191, 609, 485, 627, 1353, 0, 422, 1583, 1191, 609, 627, 485],
[1334, 1843, 1436, 734, 609, 396, 1562, 421, 0, 1745, 1436, 734, 396, 609],
[858, 1186, 864, 1042, 1229, 1879, 984, 1525, 1759, 0, 864, 1042, 1879, 1229],
[428, 466, 0, 1103, 1175, 1998, 226, 1561, 1715, 947, 0, 1103, 1998, 1175],
[663, 1119, 753, 0, 350, 1063, 901, 681, 814, 1111, 753, 0, 1063, 350],
[1488, 1994, 1591, 905, 776, 0, 1746, 603, 405, 1676, 1591, 905, 0, 776],
[906, 1395, 1003, 292, 0, 822, 1058, 479, 600, 1518, 1003, 292, 822, 0]]
[[10,11,12,13],
 [14,15,16,17],
 [18,19,20,21],
 [22,23,24,25]]
我需要同时删除say
a1
a2
a3
索引列和行。我该怎么做?整洁的方式是什么

注意,我需要得到另一个平方矩阵。应删除同一索引中的行和列。还要注意的是,删除行/列时,索引会移位。要么我也需要转换,例如
a1
a2
a3
,要么做一些更聪明的事情

例 方阵:

[[0, 516, 226, 853, 1008, 1729, 346, 1353, 1554, 827, 226, 853, 1729, 1008],
[548, 0, 474, 1292, 1442, 2170, 373, 1801, 1989, 1068, 474, 1292, 2170, 1442],
[428, 466, 0, 1103, 1175, 1998, 226, 1561, 1715, 947, 0, 1103, 1998, 1175],
[663, 1119, 753, 0, 350, 1063, 901, 681, 814, 1111, 753, 0, 1063, 350],
[906, 1395, 1003, 292, 0, 822, 1058, 479, 600, 1518, 1003, 292, 822, 0],
[1488, 1994, 1591, 905, 776, 0, 1746, 603, 405, 1676, 1591, 905, 0, 776],
[521, 357, 226, 1095, 1167, 1987, 0, 1552, 1705, 1051, 226, 1095, 1987, 1167],
[1092, 1590, 1191, 609, 485, 627, 1353, 0, 422, 1583, 1191, 609, 627, 485],
[1334, 1843, 1436, 734, 609, 396, 1562, 421, 0, 1745, 1436, 734, 396, 609],
[858, 1186, 864, 1042, 1229, 1879, 984, 1525, 1759, 0, 864, 1042, 1879, 1229],
[428, 466, 0, 1103, 1175, 1998, 226, 1561, 1715, 947, 0, 1103, 1998, 1175],
[663, 1119, 753, 0, 350, 1063, 901, 681, 814, 1111, 753, 0, 1063, 350],
[1488, 1994, 1591, 905, 776, 0, 1746, 603, 405, 1676, 1591, 905, 0, 776],
[906, 1395, 1003, 292, 0, 822, 1058, 479, 600, 1518, 1003, 292, 822, 0]]
[[10,11,12,13],
 [14,15,16,17],
 [18,19,20,21],
 [22,23,24,25]]
删除第一个和第三个索引,结果是:

[[10,12],
 [18,20]]

如果您对其他软件包持开放态度,则可以简化:

import pandas as pd

to_drop = [a1,a2,a3]
out = pd.DataFrame(a).drop(to_drop).drop(to_drop, axis=1).to_numpy()

更新:输出样本数据上的代码

array([[10, 12],
   [18, 20]])

如果您对其他软件包持开放态度,则可以简化:

import pandas as pd

to_drop = [a1,a2,a3]
out = pd.DataFrame(a).drop(to_drop).drop(to_drop, axis=1).to_numpy()

更新:输出样本数据上的代码

array([[10, 12],
   [18, 20]])

如果只需要numpy并假设数组始终为平方:

a = np.array([[10,11,12,13], 
[14,15,16,17], 
[18,19,20,21], 
[22,23,24,25]])    
valid = [r for r in range(a.shape[0]) if r not in [1,3]] 
a[valid][:,valid]
>>>array([[10, 12],
   [18, 20]])

如果只需要numpy并假设数组始终为平方:

a = np.array([[10,11,12,13], 
[14,15,16,17], 
[18,19,20,21], 
[22,23,24,25]])    
valid = [r for r in range(a.shape[0]) if r not in [1,3]] 
a[valid][:,valid]
>>>array([[10, 12],
   [18, 20]])

在numpy中尝试此方法
np.ix
为您创建一个网格网格,用于索引numpy数组的列和行。只需在方阵中的行范围和要删除的行/列的索引列表之间取
集,即可创建索引列表-

sqm = np.array([[10,11,12,13],
 [14,15,16,17],
 [18,19,20,21],
 [22,23,24,25]])

rem = [1,3] #Rows/columns to remove

idx = list(set(range(sqm.shape[0])).difference(rem))
print('Rows/columns to keep:',idx)

output = sqm[np.ix_(idx,idx)]
print(output)

编辑:下面添加了要删除的方阵10000x1000和~500行/列的基准测试结果。(MacBookPro 13)

  • Quang Hoang的方法-每个回路841 ms±8.19 ms(7次运行的平均值±标准偏差,每个回路1次)
  • MBeale方法-每个回路1.62s±48.9ms(7次运行的平均值±标准偏差,每个回路1次)
  • Akshay-Sehgal的方法-每个回路655 ms±19.4 ms(7次运行的平均值±标准偏差,每个回路1次)

在numpy中尝试此方法
np.ix
为您创建一个网格网格,用于索引numpy数组的列和行。只需在方阵中的行范围和要删除的行/列的索引列表之间取
集,即可创建索引列表-

sqm = np.array([[10,11,12,13],
 [14,15,16,17],
 [18,19,20,21],
 [22,23,24,25]])

rem = [1,3] #Rows/columns to remove

idx = list(set(range(sqm.shape[0])).difference(rem))
print('Rows/columns to keep:',idx)

output = sqm[np.ix_(idx,idx)]
print(output)

编辑:下面添加了要删除的方阵10000x1000和~500行/列的基准测试结果。(MacBookPro 13)

  • Quang Hoang的方法-每个回路841 ms±8.19 ms(7次运行的平均值±标准偏差,每个回路1次)
  • MBeale方法-每个回路1.62s±48.9ms(7次运行的平均值±标准偏差,每个回路1次)
  • Akshay-Sehgal的方法-每个回路655 ms±19.4 ms(7次运行的平均值±标准偏差,每个回路1次)

请添加一个mcve。请使用
np检查我的方法。ix
np。可以使用delete
先删除行,然后删除列。我不认为你是按顺序还是同时做这些步骤有什么区别。但是,构建能够同时选择所需行和列的索引并不困难。这就是删除时要做的事情-选择all,但不选择。
np.delete
只在一个轴上运行。您还可以使用
np.ix
创建要删除(或保留)的列和行索引。我对在两个轴上顺序应用np.delete进行了基准测试,与其他方法相比,其超慢<代码>2 s±348 ms/循环(7次运行的平均值±标准偏差,每个循环1次)
。正在尝试查找此方法是否可以同时应用于两个轴。请添加mcve。请使用
np检查我的方法。ix\ucode>
np。可以使用delete
先删除行,然后删除列。我不认为你是按顺序还是同时做这些步骤有什么区别。但是,构建能够同时选择所需行和列的索引并不困难。这就是删除时要做的事情-选择all,但不选择。
np.delete
只在一个轴上运行。您还可以使用
np.ix
创建要删除(或保留)的列和行索引。我对在两个轴上顺序应用np.delete进行了基准测试,与其他方法相比,其超慢<代码>2 s±348 ms/循环(7次运行的平均值±标准偏差,每个循环1次)
。试图找出此方法是否可以同时应用于两个轴。这是否确保删除行和列后[a1、a2、a3]的值相同?这是否确保删除行和列后[a1、a2、a3]的值相同?输入总是平方的,因此此numpy替代方案也是一个很好的答案。谢谢输入总是平方的,所以这个numpy替代方案也是一个很好的答案。谢谢有趣的是,
MBeale
方法比
Quang Hoang
的pandas方法慢。因为显式for循环和布尔索引是
[valid][:,valid]
的两倍。光环的做法可能是向大熊猫转变过程中迈出的最沉重的一步。其他pandas函数应该得到相当优化。有趣的是,
MBeale
方法比
Quang Hoang
的pandas方法慢。因为显式for循环和布尔索引2次
[valid][:,valid]
。光环的做法可能是向大熊猫转变过程中迈出的最沉重的一步。其他功能应该得到相当优化。