简体   繁体   English

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

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

Let's say I have a dataframe with a column of closing prices, and a separate (not included in the dataframe) list of max's like so:假设我有一个数据框,其中包含一列收盘价,以及一个单独的(未包含在数据框中)最大值列表,如下所示:

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

What is a pythonic way to add another column to the dataframe, where it grabs the next biggest number, comparing each close to the numbers in the list?将另一列添加到数据框中的 Pythonic 方法是什么,它获取下一个最大的数字,并将每个与列表中的数字相比较? Such that, the expected output would be:这样,预期的输出将是:

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

Something pseudo like:一些伪像:

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

...or maybe to sort the Max's list from smallest to largest and then somehow loop through each Closes and compare one at a time to see if it's less than the current Max it's trying to compare to? ...或者也许将 Max 的列表从最小到最大排序,然后以某种方式循环遍历每个 Closes 并一次比较一个以查看它是否小于它试图与之比较的当前 Max? Help!帮助! Thanks!谢谢!

One possible solution (for small datasets) is to find the minimum value of all the values in Max's that are greater than each value in Closes :一种可能的解决方案(对于小数据集)是找到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)

Output:输出:

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

A more efficient alternative would be a nested loop using a sorted Max's list:更有效的替代方法是使用排序的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)

Output:输出:

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

Use a nested loop like so:像这样使用嵌套循环:

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)

Output:输出:

   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

Here's something using generator expressions that shouldn't have problems with very large lists.这是使用生成器表达式的东西,对于非常大的列表不应该有问题。 It basically creates two generators, one that cycles over its sequence every time the other generator advances once, and which(the former) terminates the first time the matching condition is found.它基本上创建了两个生成器,一个在每次另一个生成器前进一次时循环它的序列,并且(前者)在第一次找到匹配条件时终止。 (The top answer in the reference below is very helpful) (以下参考文献中的最佳答案非常有帮助)

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

To use this function:要使用此功能:

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

This gives the following result:这给出了以下结果:

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

Based mainly on: Get the first item from an iterable that matches a condition主要基于: 从匹配条件的迭代中获取第一项

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

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