【问题标题】:Pythonic Way to Find Next Biggest Number in an Array?在数组中查找下一个最大数字的 Pythonic 方法?
【发布时间】:2020-02-28 14:27:50
【问题描述】:

假设我有一个包含收盘价列的数据框,以及一个单独的(不包含在数据框中)最大值列表,如下所示:

Closes      Max's
1           3
2           5
3           7
4           6
5           2
4
3
2
1

向数据框中添加另一列的pythonic方法是什么,它会在其中获取下一个最大的数字,并将每个列与列表中的数字进行比较?这样,预期的输出将是:

Closes      Next_Biggest
1           2
2           3
3           5
4           5
5           6
4           5
3           5
2           3
1           2

类似的伪类:

df['Next_Biggest'] = i where df['Closes'] > i and < i for i in Max's 

...或者也许将 Max 的列表从小到大排序,然后以某种方式循环每个 Closes 并一次比较一个,看看它是否小于它试图比较的当前 Max?帮助!谢谢!

【问题讨论】:

  • 您的数据有多大?

标签: python python-3.x pandas numpy


【解决方案1】:

一种可能的解决方案(对于小型数据集)是找到Max's 中大于Closes 中每个值的所有值的最小值:

closes = [1, 2, 3, 4, 5, 4, 3, 2, 1]
maxs = [3, 5, 6, 7, 2]
nextbig = [min([m for m in maxs if m > c]) for c in closes]
print(nextbig)

输出:

[2, 3, 5, 5, 6, 5, 5, 3, 2]

更有效的替代方法是使用排序的Max's 列表的嵌套循环:

closes = [1, 2, 3, 4, 5, 4, 3, 2, 1]
maxs = [3, 5, 6, 7, 2]
nextbig = [c for c in closes]
maxs.sort()
for m in maxs:
    for i, c in enumerate(closes):
        if m > c and nextbig[i] == c:
            nextbig[i] = m
print(nextbig)

输出:

[2, 3, 5, 5, 6, 5, 5, 3, 2]

【讨论】:

  • 谢谢!让这个在我的应用程序上工作。像魅力一样工作。
【解决方案2】:

像这样使用嵌套循环:

import pandas as pd
# example dataframe without maxs inside the frame
d = {'Closes': [1, 2, 3, 4, 5, 4, 3, 2, 1]}
# maxs as a list
maxs = [3,5,7,6,2]
# sort the list from least to greatest
maxs.sort()
# have a container for new column
nextBiggest = []
# set up data frame
dataFrame = pd.DataFrame(data=d)
# convert data frame object to a list
dList = dataFrame.values.tolist()
# using a nested loop, find next biggest and put into nextBiggest list
for element in dList:
    for value in element:
        for max in maxs:
            if max > value:
                nextBiggest.append(max)
                break
# add nextBiggest list as a column to the dataframe
dataFrame['Next Biggest'] = nextBiggest
# display results
print(dataFrame)

输出:

   Closes  Next Biggest
0       1             2
1       2             3
2       3             5
3       4             5
4       5             6
5       4             5
6       3             5
7       2             3
8       1             2

【讨论】:

    【解决方案3】:

    这里有一些使用生成器表达式的东西,对于非常大的列表应该不会有问题。它基本上创建了两个生成器,一个在每次另一个生成器前进一次时循环其序列,并且(前者)在第一次找到匹配条件时终止。 (下面参考中的顶级答案非常有帮助)

    def find_next_largest(closes, maxes):
        """Searches through one list trying to find the next largest value
        from another list."""
        maxes = sorted(maxes)
        foo = (i for i in closes)  #generator for closes, the very large list
        for x in range(len(closes)):
            test = next(foo)
            bar = next((test, val) for val in maxes if val > test) #see SO reference below
            yield bar
    

    要使用这个功能:

    closes = [1,2,3,4,5,4,3,2,1]
    maxes = [2,3,4,6,7]
    zed = find_next_largest(closes, maxes)
    result = []
    while True:
        try:
            result.append(next(zed))
        except StopIteration:
            break
    

    这给出了以下结果:

    [(1, 2), (2, 3), (3, 4), (4, 6), (5, 6), (4, 6), (3, 4), (2, 3), (1, 2)]
    

    主要基于: Get the first item from an iterable that matches a condition

    【讨论】:

    • 有趣,从没想过使用生成器。很好地解决这个问题。谢谢!
    猜你喜欢
    • 2017-12-23
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 2011-10-08
    • 1970-01-01
    • 2011-01-15
    相关资源
    最近更新 更多