繁体   English   中英

在数组中查找下一个最大数字的 Pythonic 方法?

[英]Pythonic Way to Find Next Biggest Number in an Array?

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

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? 帮助! 谢谢!

一种可能的解决方案(对于小数据集)是找到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]

像这样使用嵌套循环:

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

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

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)]

主要基于: 从匹配条件的迭代中获取第一项

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM