【问题标题】:Sorting lists with indexing for easy item removal使用索引对列表进行排序,以便轻松删除项目
【发布时间】:2021-09-02 10:57:50
【问题描述】:

我面临以下问题。我在 Python 中有多个列表,我希望它们使用某种索引对它们进行排序,以便从其他列表中删除项目。让我进一步解释。

listA_ID = [1,2,3,5,6,7] # integer from 0-250
listA_Var1 = [3.9, 4.7, 2.1, 1.2, 0.15, 0.99]

listB_ID = [2,5,6,7,8,10] # integer from 0-250
listB_Var1 = [0.54, 0.35, 1.19, 2.45, 3.1, 1.75]
>> After Comparison of listA_ID & listB_ID I should end up with the common IDs.
listA_ID = listB_ID = sorted(list(set(listA_ID) & set(listB_ID)))
listA_ID = [2,5,6,7]
listB_ID = [2,5,6,7]

因此,我想从 listA_ID 中删除位于该列表 [0, 2] 位置的元素 [1, 3],并从 listA_Var1 中删除相同的元素,删除位于相同位置的 [3.9, 2.1] [0, 2]。

同样,我想从 listB_ID 中删除位于该列表 [4, 5] 位置的元素 [8, 10] 和 listB_Var1 中的相同内容,删除相同的 [3.1, 1.75]位置 [4, 5]。

>> and then listA_Var1 & listB_Var1 will become
listA_Var1 = [4.7, 1.2, 0.15, 0.99]
listB_Var1 = [0.54, 0.35, 1.19, 2.45]

关于有效实施该方法的任何想法?根据我大量使用 Matlab 的经验,在比较两个列表之后,我有办法获取不需要的索引,然后将这些索引应用于列表,我得到的是最终列表 listA_Var1 和 listB_Var1。

有什么想法吗?提前致谢!

【问题讨论】:

  • 这个问题的pandas numpy 方面是什么?
  • 我对“pandas”这个词有点陌生(老实说),但是,我认为 numpy 可能是 Matlab 风格的解决方案。

标签: python numpy sorting lambda


【解决方案1】:

1.获得路口

有很多方法可以做到这一点。有关详细讨论,请参阅here。正如那里所建议的那样,如果重复项无关紧要(即您的列表要么不包含重复项,要么它们包含但您不关心它们),例如,您可以使用set() 来获取共同价值观:

intersection_A_B = sorted(list(set(listA_ID) & set(listB_ID)))

Alternatively,也可以只将其中一个列表变成一个集合,然后使用intersection()方法,如:

intersection_A_B = list(set(listA_ID).intersection(listB_ID))

相比之下,如果重复很重要或可能造成问题(例如,listA_IDlistB_ID 都包含两次值,并且您希望您的交集保留该值的两个列表),而不是使用set()intersection(),你可以use list comprehension:

intersection_A_B = [x for x in listA_ID if x in listB_ID]

2。删除值

编辑:得到交叉点后(注意,现在我得到了你真正想要的东西,过程的第一步指的是intersection_A_B,而不是更新listA_ID和@987654335 @ 因为以下操作需要它们的原始状态),这应该可以解决问题:

del_indices_A = [i for i, value in enumerate(listA_ID) if value not in intersection_A_B]
listA_Var1 = [listA_Var1[x] for x in range(len(listA_Var1)) if x not in del_indices_A]

del_indices_B = [i for i, value in enumerate(listB_ID) if value not in intersection_A_B]
listB_Var1 = [listB_Var1[x] for x in range(len(listB_Var1)) if x not in del_indices_B]

这首先检查listA_IDlistB_ID 中的哪些索引对应于intersection_A_B 中未包含的值,然后排除与listA_Var1listB_Var2 中的索引对应的值。

【讨论】:

  • 这是一个使用 set +1 的优雅解决方案。
  • 非常感谢@Georgy Kopshteyn。不过,我并没有把自己说得很清楚。 A1, A2... 或 B1, B2,... 不会是字符串,而是数字,确切地说是浮点数。我只是希望能够在操作“listA_ID = listB_ID = list(set(listA_ID) & set(listB_ID))”之后从listA_Var1 & listB_Var1中提取相应的元素
  • 我还推荐使用像sorted(set(listA_ID).intersection(listB_ID))这样的排序元素
  • 我可能有重复的数字,但操作 "listA_ID = listB_ID = list(set(listA_ID) & set(listB_ID))" 似乎只保留它找到的第一个重复,这适合我需要!
  • @V.Nikolaidis 如果您需要将它们转换为浮点数,只需使用float() 而不是字符串格式。例如:listA_float = [float(x) for x in listA_ID] 会给你[2.0, 5.0, 6.0, 7.0, 8.0, 9.0, 14.0]。这是你的想法吗?
【解决方案2】:

首先,我将逐步解释这种方法:

- 第 1 步: 我们将在 listA_IDlistB_ID 中寻找交集元素。

intersection_AB = set(listA_ID) & set(listB_ID)

- 第 2 步: 然后,我们执行 difference of sets。将set(listA_ID)放在首位非常重要,因为the difference of sets is not commutative

# You can use difference() method alternatively:
# A_elements = list(set(listA_ID).difference(intersection_AB)) but personally I like the minus operator.

A_elements = list(set(listA_ID) - intersection_AB) 

- 第 3 步: 然后,我们根据上一步中找到的元素查找索引。

index_to_remove_list_A = [listA_ID.index(i) for i in A_elements]

或者你也可以使用(虽然不太清晰):

index_to_remove_list_A = [listA_ID.index(i) for i in list(set(listA_ID) - intersection_AB)]

- 第 4 步: 删除列表中正确的元素。

for i in sorted(index_to_remove_list_A, reverse=True):
  del listA_Var1[i]

print(listA_Var1)

编辑:包含两个列表的完整代码...

A_elements = list(set(listA_ID) - intersection_AB)
B_elements = list(set(listB_ID) - intersection_AB)

index_to_remove_list_A = [listA_ID.index(i) for i in A_elements]
index_to_remove_list_B = [listB_ID.index(i) for i in B_elements]

for i in sorted(index_to_remove_list_A, reverse=True):
  del listA_Var1[i]

for i in sorted(index_to_remove_list_B, reverse=True):
  del listB_Var1[i]


print(listA_Var1) # [4.7, 1.2, 0.15, 0.99]
print(listB_Var1) # [0.54, 0.35, 1.19, 2.45]

【讨论】:

  • 您的解决方案@CarMoreno 在使用 difference() 方法而不是 (-) 符号时也能正常工作。我不明白为什么,因为我在别处见过。非常感谢您的宝贵时间!!!
【解决方案3】:

好吧,我自己也会发布一个可行的解决方案,使用 numpy。

intersection_A_B = sorted(list(set(listA_ID) & set(listB_ID)))

# Convert Lists to Arrays
np_listA_ID = np.asarray( listA_ID )
np_listB_ID = np.asarray( listB_ID )

# Comparison of two arrays
np_list_ID, listA_ind, listB_ind = np.intersect1d(np_listA_ID, np_listB_ID, assume_unique=False, return_indices=True)

# Keep only Items Needed    
np_listA_Var1 = np.asarray( listA_Var1 )
np_listB_Var1 = np.asarray( listB_Var1 )

# Covert Array to List again
listA_ID=listB_ID=np_list_ID.tolist()
listA_Var1 = np_listA_Var1[listA_ind].tolist()
listB_Var1 = np_listB_Var1[listB_ind].tolist()

【讨论】:

    猜你喜欢
    • 2010-09-18
    • 2012-09-07
    • 2013-12-03
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多