消除python列表中的n个最高值

时间:2019-09-18 15:05:54

标签: python pandas

我有一个如下所示的列表:

@model App.ViewModels.CharacterWithItemViewModel

<div class="row form-group" style="margin-top:15px">
    <div class="col-md-6">
        <div class="text-right">
            <div>
                <div class="text-left align-top">
                    Name: @Model.character.CharName CharacterId: @Model.character.ObjId ItemId: @Model.item.ItemId 
                    <div id="Test">
                        Count: @Model.item.Count
                    </div>
                    </div>
            </div>
        </div>
    </div>
    <div class="col-md-6 text-right">
        <form asp-controller="CharacterAndItems" asp-action="AddItems"
              data-ajax="true" data-ajax-method="post"
              data-ajax-mode="replace" data-ajax-update="#Test">
            <input type="hidden" name="characterId" value="@Model.character.ObjId" />
            <input type="hidden" name="itemId" value="@Model.item.ItemId" />
            <input class="form" placeholder="Item quantity" name="count" style="text-align:center" />
            <input type="submit" value="Add items" name="add" class="btn btn-primary" />
            <input type="submit" value="Delete items" name="delete" class="btn btn-danger" />
        </form>
    </div>
</div>

@section Scripts {
    <script>
        $.ajax({
            url: '/CharacterAndItems/AddItems',
            type = 'POST',
            data: JSON.stringify(@Model)
        })
        var results = $("#Results");
    </script>
}

丢弃列表中的两个最高值的最简单方法是什么?

熊猫走的路吗?像这样:

List = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]

类似的东西

import pandas as pd
df = pd.DataFrame(
    List, 
    index =['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'], 
    columns =['Names']
)

我发现非常麻烦的事情是在pandas数据帧IE中手动定义df = df.nsmallest(len(List)-2, 'Names') ,手动输入index可以进行for循环吗?

谢谢

5 个答案:

答案 0 :(得分:3)

考虑到问题的简单性,这是香草Python中的一种可能的解决方案,我看不出使用Pandas的明确理由:

my_list = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
n = 2
print (sorted(my_list)[:len(my_list)-n])

输出

[34, 36, 44, 55, 66, 78, 78, 83, 89]

使用的技术称为切片,可根据我们的需求轻松剪切列表。

下面是一个简单的示例,可以快速了解其工作原理:

a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array

我刚刚阅读了@EliasStrehle的评论,它很好地说明了将原始列表作为一个整体(完整副本)保存的潜在需要。

如果我们想保留原始列表的副本:

my_list = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
new_list = sorted(my_list)
n = 2
new_list = new_list[:len(new_list)-n]
print("Original list:")
print(my_list)
print("New list:")
print (new_list)

输出

Original list:
[83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
New list:
[34, 36, 44, 55, 66, 78, 78, 83, 89]

如果我们只想保持列表顺序:

my_list = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
n = 2
for times in range(n):
    my_list.remove(max(my_list))
print(my_list)


# Another way of writing the same thing in a more cryptic / minimalistic oneliner
l = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
[l.remove(max(l)) for _ in range(2)]

输出

[83, 36, 44, 66, 78, 34, 78, 55, 89]

答案 1 :(得分:1)

熊猫确实是解决此问题的简单方法。您可以使用Series.rank

l = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
s = pd.Series(l)

s[s.rank().le(len(l)-2)].values.tolist()
# [83, 36, 44, 66, 78, 34, 78, 55, 89]

或者使用nlargest作为@anky建议:

s.drop(s.nlargest(2).index).values.tolist()

答案 2 :(得分:1)

我同意Pitto,不需要通过使用Pandas来减慢自己的速度。 此解决方案保留了原始列表的顺序。 它在最后一行中使用列表推导。列表理解很快速(而且很有趣)!

my_list = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
n = 2

my_list_sorted = sorted(my_list)
nth_highest = my_list_sorted[-n]  # Requires n <= len(my_list)

my_list_filtered = [x for x in my_list if x < nth_highest]

答案 3 :(得分:1)

如果输出的顺序无关紧要,则可以使用heapq

import heapq

lst = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
heapq._heapify_max(lst)  # convert to a heap O(n)
[heapq._heappop_max(lst) for _ in range(2)]  # pop the k max items O(k*log(n))

print(lst)

输出

[89, 83, 78, 66, 78, 34, 44, 55, 36]

此解决方案的复杂度为O(n + k*log(n)),而排序则更昂贵O(n*log(n))

答案 4 :(得分:1)

numpy解决方案:

List = [83, 36, 44, 66, 78, 34, 78, 55, 89, 100, 97]
np.array(List)[np.argsort(List)[:-2]]

输出:

array([34, 36, 44, 55, 66, 78, 78, 83, 89])