Python 删除多个列表的索引(如果它们相等)
我试图从两个列表中删除索引,如果两个列表中的给定索引值都等于0。下面我已经编写了一种方法来实现这一点,但我的实际数据集包括>11K个列表和>30K个索引 那么我的问题是,有没有一种更简单/更有效的方法Python 删除多个列表的索引(如果它们相等),python,arrays,list,dictionary,indexing,Python,Arrays,List,Dictionary,Indexing,我试图从两个列表中删除索引,如果两个列表中的给定索引值都等于0。下面我已经编写了一种方法来实现这一点,但我的实际数据集包括>11K个列表和>30K个索引 那么我的问题是,有没有一种更简单/更有效的方法 data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]] # taking the sum of indices across all arrays if it equals 0 you know that that index is 0 across all array
data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]]
# taking the sum of indices across all arrays if it equals 0 you know that that index is 0 across all arrays
sum_dict = {}
for array in data:
for i in range(len(array)):
value = array[i]
if i not in sum_dict:
sum_dict[i] = value
else:
sum_dict[i] += value
# removing indices that have sum=0 in all arrays and create "clean" data
clean_data = []
sum_dict = {key:val for key, val in sum_dict.items() if val == 0}
for array in data:
for i in sorted(list(sum_dict.keys()), reverse=True):
del array[i]
clean_data.append(array)
print(clean_data)
输出:
[[8, 3, 0, 1, 1], [1, 2, 8, 0, 3]]
您可以将两个列表一起迭代,只在两个元素不等于0时考虑元素。您可以使用来同时迭代这两个元素
data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]]
result = []
for i, j in zip(*data):
# Only consider the elements if both i and j are not equal to 0
if not (i == j and i == 0):
result.append((i, j))
result = [list(data) for data in zip(*result)]
print(result)
输出是
[[8, 3, 0, 1, 1], [1, 2, 8, 0, 3]]
对于多个子列表的更一般的情况,可以使用以下方法
result = []
for elements in zip(*data):
# Only consider if it is not the case that all elements are equal to 0
if not all(x==0 for x in elements):
result.append(elements)
result = [list(data) for data in zip(*result)]
print(result)
您可以将两个列表一起迭代,只在两个元素不等于0时考虑元素。您可以使用来同时迭代这两个元素
data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]]
result = []
for i, j in zip(*data):
# Only consider the elements if both i and j are not equal to 0
if not (i == j and i == 0):
result.append((i, j))
result = [list(data) for data in zip(*result)]
print(result)
输出是
[[8, 3, 0, 1, 1], [1, 2, 8, 0, 3]]
对于多个子列表的更一般的情况,可以使用以下方法
result = []
for elements in zip(*data):
# Only consider if it is not the case that all elements are equal to 0
if not all(x==0 for x in elements):
result.append(elements)
result = [list(data) for data in zip(*result)]
print(result)
我能想到的最简单的方法就是使用numpy。如果
数据
中的所有列表长度相同,则尤其如此:
import numpy as np
data = np.array(data)
sums = data.sum(axis=0)
clean_data = data[:, sums.astype(bool)]
计算掩码的速度可能稍快,但内存效率要低得多
mask = (data != 0).any(axis=0)
clean_data = data[:, mask]
如果您的数据参差不齐,或者出于其他原因只想使用普通python,那么还有更好的方法。可以从最长基准面大小的零列表开始。字典是不必要的,因为对于连续索引,列表是int到value的更好映射
maxlen = max(len(d) for d in data)
sums = [0] * maxlen
更新总数相当简单。一种选择是使用zip
:
for d in data:
sums[:len(d)] = [s + t for s, t in zip(sums, d)]
可通过以下方式方便清理数据:
只有当你是一个受虐狂,而且数据不完整时,你才会这样做。如果数据不是杂乱无章的,并且不能使用numpy,请使用中的换位习惯用法。我能想到的最简单的方法就是使用numpy。如果
数据
中的所有列表长度相同,则尤其如此:
import numpy as np
data = np.array(data)
sums = data.sum(axis=0)
clean_data = data[:, sums.astype(bool)]
计算掩码的速度可能稍快,但内存效率要低得多
mask = (data != 0).any(axis=0)
clean_data = data[:, mask]
如果您的数据参差不齐,或者出于其他原因只想使用普通python,那么还有更好的方法。可以从最长基准面大小的零列表开始。字典是不必要的,因为对于连续索引,列表是int到value的更好映射
maxlen = max(len(d) for d in data)
sums = [0] * maxlen
更新总数相当简单。一种选择是使用zip
:
for d in data:
sums[:len(d)] = [s + t for s, t in zip(sums, d)]
可通过以下方式方便清理数据:
只有当你是一个受虐狂,而且数据不完整时,你才会这样做。如果数据不参差不齐且无法使用numpy,请使用中的换位习惯用法。另一种使用pandas的解决方案:
将熊猫作为pd导入
数据=pd.数据帧([[8,0,3,0,1,0,1],[1,0,2,8,0,0,3])
data=data.loc[:,data.sum(轴=0)!=0]
打印(数据值)
"""
[[8 3 0 1 1]
[1 2 8 0 3]]
"""
另一种使用熊猫的解决方案:
将熊猫作为pd导入
数据=pd.数据帧([[8,0,3,0,1,0,1],[1,0,2,8,0,0,3])
data=data.loc[:,data.sum(轴=0)!=0]
打印(数据值)
"""
[[8 3 0 1 1]
[1 2 8 0 3]]
"""
另一种解决方案:
data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]]
intermediate = ( x for x in zip(*data) if not (x == (0, 0) ) )
result = [ list(item) for item in zip(*intermediate) ]
print(result)
另一个解决方案:
data = [[8,0,3,0,1,0,1],[1,0,2,8,0,0,3]]
intermediate = ( x for x in zip(*data) if not (x == (0, 0) ) )
result = [ list(item) for item in zip(*intermediate) ]
print(result)
这是一个很好的例子,说明了为什么发布清晰的代码很重要。你的散文本身有点难以理解,代码也是如此。但在一起,你们有一个非常明确的问题,我很乐意回答。干得好!所有的清单都一样长吗?还是数据不完整?谢谢,我很乐意接受你的建议!如果有什么不清楚的地方,请告诉我@pr94,如果两个子列表的长度不相同,例如,
data=[[1,2,0],[3,4]]
,那么应该是什么输出所有列表的长度确实相等,列表中的位置表示给定的特征。例如,两个列表中的索引5都显示特征x的值。希望这有帮助!这是一个很好的例子,说明了为什么发布清晰的代码很重要。你的散文本身有点难以理解,代码也是如此。但在一起,你们有一个非常明确的问题,我很乐意回答。干得好!所有的清单都一样长吗?还是数据不完整?谢谢,我很乐意接受你的建议!如果有什么不清楚的地方,请告诉我@pr94,如果两个子列表的长度不相同,例如,data=[[1,2,0],[3,4]]
,那么应该是什么输出所有列表的长度确实相等,列表中的位置表示给定的特征。例如,两个列表中的索引5都显示特征x的值。希望这有帮助!谢谢,您的第二段代码似乎确实有效。正如我们所说,我正在真实的数据集上运行它。集合转换似乎效率低下。如果要检查每个元素是否为零,则不需要使用哈希表来方便:all(x==0表示x元素中的x)
就可以了,而且可能比all
快得多,设置的转换是O(n)
时间,但我想all
节省空间,短路速度更快?是的,而且all
不会构建哈希表。并非所有的O(n)
算法都同样快速是的,对于all
来说,最佳情况下的时间复杂度更好,这要感谢您的第二段代码似乎确实有效。正如我们所说,我正在真实的数据集上运行它。集合转换似乎效率低下。如果要检查每个元素是否为零,则不需要使用哈希表来方便:all(x==0表示x元素中的x)
就可以了,而且可能比all
快得多,设置的转换是O(n)
时间,但我想all
节省空间,短路速度更快?是的,而且all
不会构建哈希表。并非所有的O(n)
算法都同样快速是的,对于all
Wow,最佳情况下的时间复杂度更好,这是一个使用numpy@Devesh. 是的,这些数组只有几MB,所以我想至少有几个数量级的加速。在实际数据集上运行它,该数据集包含>11K个索引>30K的子列表。运行时间不到10秒(您的第一个选项)。太好了@pr94>300MB很大,但numpy很快:)我敢打赌