在熊猫中从n种可能性中有效选择r个结果

时间:2019-01-30 07:08:07

标签: python pandas discrete-mathematics apriori

我有50年的数据。我需要从中选择30年的组合,以使对应于它们的值达到特定的阈值,但是50C30的可能组合数为47129212243960。 如何有效地计算?

          Prs_100      
  Yrs                                                 
  2012  425.189729  
  2013  256.382494  
  2014  363.309507  
  2015  578.728535  
  2016  309.311562  
  2017  476.388839  
  2018  441.479570  
  2019  342.267756  
  2020  388.133403  
  2021  405.007245  
  2022  316.108551  
  2023  392.193322  
  2024  296.545395  
  2025  467.388190  
  2026  644.588971  
  2027  301.086631  
  2028  478.492618  
  2029  435.868944  
  2030  467.464995  
  2031  323.465049  
  2032  391.201598  
  2033  548.911349  
  2034  381.252838  
  2035  451.175339  
  2036  281.921215  
  2037  403.840004  
  2038  460.514250  
  2039  409.134409  
  2040  312.182576 
  2041  320.246886  
  2042  290.163454  
  2043  381.432168  
  2044  259.228592  
  2045  393.841815  
  2046  342.999972  
  2047  337.491898  
  2048  486.139010  
  2049  318.278012  
  2050  385.919542  
  2051  309.472316  
  2052  307.756455  
  2053  338.596315  
  2054  322.508536  
  2055  385.428138  
  2056  339.379743  
  2057  420.428529  
  2058  417.143175 
  2059  361.643381  
  2060  459.861622  
  2061  374.359335

我只需要使用30年的组合,其Prs_100的平均值就可以达到某个阈值,那么我就可以不再计算其他结果了。在搜索SO时,我发现了一种使用apriori算法的特殊方法但无法真正弄清楚其中的支持价值。

我用过python的组合方法

 list(combinations(dftest.index,30))

但在这种情况下不起作用。

预期结果- 假设我发现一个30年集合,其Prs_100平均值大于460,那么我将保存这30年的输出,这也是我期望的结果。 怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用numpy的random.choice

In [11]: df.iloc[np.random.choice(np.arange(len(df)), 3)]
Out[11]:
         Prs_100
Yrs
2023  392.193322
2047  337.491898
2026  644.588971

答案 1 :(得分:1)

我先前的答案是不合时宜的,因此我将再次尝试。通过重新阅读您的问题,您似乎正在寻找30年的一次结果,其中Prs_100值的平均值大于460。

下面的代码可以做到这一点,但是当我运行它时,在大约415的平均值之后,我开始遇到困难。

运行后,您会得到一个年份列表“ years_list”和一个值列表“ Prs_100_list”,它们符合均值> 460的标准(在下面的示例中为415)。

这是我的代码,希望这是您正在寻找的区域。

from math import factorial
import numpy as np
import pandas as pd
from itertools import combinations
import time

# start a timer
start = time.time()

# array of values to work with, corresponding to the years 2012 - 2062
prs_100 = np.array([
       425.189729, 256.382494, 363.309507, 578.728535, 309.311562,
       476.388839, 441.47957 , 342.267756, 388.133403, 405.007245,
       316.108551, 392.193322, 296.545395, 467.38819 , 644.588971,
       301.086631, 478.492618, 435.868944, 467.464995, 323.465049,
       391.201598, 548.911349, 381.252838, 451.175339, 281.921215,
       403.840004, 460.51425 , 409.134409, 312.182576, 320.246886,
       290.163454, 381.432168, 259.228592, 393.841815, 342.999972,
       337.491898, 486.13901 , 318.278012, 385.919542, 309.472316,
       307.756455, 338.596315, 322.508536, 385.428138, 339.379743,
       420.428529, 417.143175, 361.643381, 459.861622, 374.359335])

# build dataframe with prs_100 as index and years as values, so that  years can be returned easily.
df = pd.DataFrame(list(range(2012, 2062)), index=prs_100, columns=['years'])

df.index.name = 'Prs_100'

# set combination parameters
r =  30
n = len(prs_100)

Prs_100_list = []
years_list = []
count = 0    

for p in combinations(prs_100, r):
    if np.mean(p) > 391 and np.mean(p) < 400:
        Prs_100_list.append(p)
        years_list.append(df.loc[p,'years'].values.tolist())
        # build in some exit
        count += 1
        if count > 100: 
            break