python按数据块过滤2d数组
我有以下2d数组。让我们按上述顺序调用字段python按数据块过滤2d数组,python,arrays,numpy,Python,Arrays,Numpy,我有以下2d数组。让我们按上述顺序调用字段a、b、c、d,其中列b类似于id。我希望删除列d中编号为“1”的所有单元格(列b(相同id)中编号相同的所有单元格),因此过滤后我将得到以下结果: import numpy as np data = np.array([ [20, 0, 5, 1], [20, 0, 5, 1], [20, 0, 5, 0], [20, 1, 5, 0], [20, 1, 5, 0], [2
a、b、c、d
,其中列b
类似于id
。我希望删除列d
中编号为“1”的所有单元格(列b
(相同id)中编号相同的所有单元格),因此过滤后我将得到以下结果:
import numpy as np
data = np.array([
[20, 0, 5, 1],
[20, 0, 5, 1],
[20, 0, 5, 0],
[20, 1, 5, 0],
[20, 1, 5, 0],
[20, 2, 5, 1],
[20, 3, 5, 0],
[20, 3, 5, 0],
[20, 3, 5, 1],
[20, 4, 5, 0],
[20, 4, 5, 0],
[20, 4, 5, 0]
])
已从数据中删除b=1
和b=4
的所有行
总而言之,因为我看到的答案并不合适。我们通过b
列查看数据块。如果一个完整的数据块在列d
中甚至没有一个数字“1”的外观,我们将删除该b
项的所有行。在下面的示例中,我们可以看到b=1
和b=4
(“id”=1和“id”=4)的数据块在d
列中数字“1”的外观为0。这就是为什么它会从数据代码中删除的原因:
[[20 0 5 1]
[20 0 5 1]
[20 0 5 0]
[20 2 5 1]
[20 3 5 0]
[20 3 5 0]
[20 3 5 1]]
结果:
import numpy as np
my_list = [[20,0,5,1],
[20,0,5,1],
[20,0,5,0],
[20,1,5,0],
[20,1,5,0],
[20,2,5,1],
[20,3,5,0],
[20,3,5,0],
[20,3,5,1],
[20,4,5,0],
[20,4,5,0],
[20,4,5,0]]
all_ids = np.array(my_list)[:,1]
unique_ids = np.unique(all_ids)
indices = [np.where(all_ids==ui)[0][0] for ui in unique_ids ]
final = []
for id in unique_ids:
try:
tmp_group = my_list[indices[id]:indices[id+1]]
except:
tmp_group = my_list[indices[id]:]
if 1 in np.array(tmp_group)[:,3]:
final.extend(tmp_group)
print np.array(final)
这将删除第二个位置为1的所有行:
[[20 0 5 1]
[20 0 5 1]
[20 0 5 0]
[20 2 5 1]
[20 3 5 0]
[20 3 5 0]
[20 3 5 1]]
这将删除第二个位置为1的所有行,除非第四个位置也是1:
[sublist for sublist in list_ if sublist[1] != 1]
通用方法:这里有一种使用和解决通用情况的方法-
[sublist for sublist in list_ if not (sublist[1] == 1 and sublist[3] != 1) ]
样本运行-
unq,tags = np.unique(data[:,1],return_inverse=1)
goodIDs = np.flatnonzero(np.bincount(tags,data[:,3]==1)>=1)
out = data[np.in1d(tags,goodIDs)]
goodIDs = np.flatnonzero(np.bincount(data[:,1],data[:,3]==1)>=1)
out = data[np.in1d(data[:,1],goodIDs)]
特定案例方法:如果第二列数据总是排序的,并且序列号从0
开始,我们可以使用简化版本,如下所示-
In [15]: data
Out[15]:
array([[20, 10, 5, 1],
[20, 73, 5, 0],
[20, 73, 5, 1],
[20, 31, 5, 0],
[20, 10, 5, 1],
[20, 10, 5, 0],
[20, 42, 5, 1],
[20, 54, 5, 0],
[20, 73, 5, 0],
[20, 54, 5, 0],
[20, 54, 5, 0],
[20, 31, 5, 0]])
In [16]: out
Out[16]:
array([[20, 10, 5, 1],
[20, 73, 5, 0],
[20, 73, 5, 1],
[20, 10, 5, 1],
[20, 10, 5, 0],
[20, 42, 5, 1],
[20, 73, 5, 0]])
样本运行-
unq,tags = np.unique(data[:,1],return_inverse=1)
goodIDs = np.flatnonzero(np.bincount(tags,data[:,3]==1)>=1)
out = data[np.in1d(tags,goodIDs)]
goodIDs = np.flatnonzero(np.bincount(data[:,1],data[:,3]==1)>=1)
out = data[np.in1d(data[:,1],goodIDs)]
另外,如果data[:,3]
总是有1和0,我们可以使用data[:,3]
代替上面列出的代码中的data[:,3]==1
基准测试
让我们在更大数组的特定情况下对矢量化方法进行基准测试-
In [44]: data
Out[44]:
array([[20, 0, 5, 1],
[20, 0, 5, 1],
[20, 0, 5, 0],
[20, 1, 5, 0],
[20, 1, 5, 0],
[20, 2, 5, 1],
[20, 3, 5, 0],
[20, 3, 5, 0],
[20, 3, 5, 1],
[20, 4, 5, 0],
[20, 4, 5, 0],
[20, 4, 5, 0]])
In [45]: out
Out[45]:
array([[20, 0, 5, 1],
[20, 0, 5, 1],
[20, 0, 5, 0],
[20, 2, 5, 1],
[20, 3, 5, 0],
[20, 3, 5, 0],
[20, 3, 5, 1]])
让我们假设如下:
b>=0
b
是一个整数
b
相当密集,即max(b)~=len(unique(b))
下面是一个使用以下方法的解决方案:
np.logical\u或.at(is\u ok,b\u vals,d\u vals)
是一个更有效的版本:
# unpack for clarity - this costs nothing in numpy
b_vals = data[:,1]
d_vals = data[:,3]
# build an array indexed by b values
is_ok = np.zeros(np.max(b_vals) + 1, dtype=np.bool_)
np.logical_or.at(is_ok, b_vals, d_vals)
# is_ok == array([ True, False, True, True, False], dtype=bool)
# take the rows which have a b value that was deemed OK
result = data[is_ok[b_vals]]
未经测试,因为很匆忙,但这应该有效:
for idx, val in zip(b_vals, d_vals):
is_ok[idx] = np.logical_or(is_ok[idx], val)
这是列表列表,还是numpy数组?试过什么了吗?这是numpy数组。它由以下命令生成:result=np.loadtxt(“name.csv”,delimiter=“,”).astype(int)。文件中的一行如下所示:5.000020090.0000,0.1854,1.000请将您的问题包含在代码中。注释不适用于codeDone。问题更清楚了吗?我的意思是添加numpy代码,但我不想具体删除我的列表[1]==1的行。只有当我的_列表[1]=I在我的_列表[3]中也是0的所有行时,我才想删除这些行@eranmose我明白了,给我一点时间,我正在修复它。我创建了一个不同的示例,你可以检查它now@EranMoshe现在检查一下很好。。但是运行时间是疯狂的。。tmp_组=[我的_列表中的项目对应的项目如果项目[1]==id]只是运行时间的一部分,则数据按“b”排序列我需要一个在数据上迭代恒定次数的解决方案实际要求是去掉任何第二列中的值与任何行中最后一列中的1不匹配的行。理论上这应该比我的答案慢一点,对吗?既然这是O(max(b)*N)
,我想我的是O(N)
?或者我误解了np.inad
的复杂性了吗?@Eric Wellnp.inad
没有完成与np.logical\u或.at
完全相同的任务,因此我无法对性能发表评论。当然,在使用进行索引之后[b\u vals]
会得到相同的布尔数组,因此它似乎与np.logical\u或.at
一起使用,我们也需要索引。添加了一些运行时测试来计时方法本身,如果您正在寻找的话。