在 Pandas 中有效地从 n 个可能性中选择 r 个结果
Choose r outcomes from n possibilities efficiently in Pandas
我有一个 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
我只需要 Prs_100
平均值达到某个阈值的 30 年组合,然后我可以停止进一步计算 outcomes.On 搜索 SO,我找到了一种使用 apriori
算法,但无法真正弄清楚其中的支持值。
我用过python
的组合方法
list(combinations(dftest.index,30))
但在这种情况下它不起作用。
预期结果-
假设我找到了一个 30 年的集合,其 Prs_100
的平均值大于 460 ,那么我将保存这 30 年的输出作为结果,这也将是我想要的结果。
怎么做?
你可以使用 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
我之前的回答有误所以我要再试一次。通过重新阅读您的问题,您似乎正在寻找一个 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
我有一个 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
我只需要 Prs_100
平均值达到某个阈值的 30 年组合,然后我可以停止进一步计算 outcomes.On 搜索 SO,我找到了一种使用 apriori
算法,但无法真正弄清楚其中的支持值。
我用过python
的组合方法 list(combinations(dftest.index,30))
但在这种情况下它不起作用。
预期结果-
假设我找到了一个 30 年的集合,其 Prs_100
的平均值大于 460 ,那么我将保存这 30 年的输出作为结果,这也将是我想要的结果。
怎么做?
你可以使用 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
我之前的回答有误所以我要再试一次。通过重新阅读您的问题,您似乎正在寻找一个 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