TLDR: 如何在不明确指定列或其值的情况下,遍历pandas数据框中多个列的所有选项?
详细版本: 我有一个pandas数据框,看起来像这样,但实际上它包含了更多功能或药物剂量组合,而不仅仅是这里列出的这些。除了3种类型的功能,它可能有70种…:
> dosage_dfFirst Score Last Score A_dose B_dose C_dose22 28 1 40 13055 11 2 40 13015 72 3 40 13042 67 1 90 13090 74 2 90 13087 89 3 90 13014 43 1 40 70012 61 2 40 70041 5 3 40 700
除了我的数据框外,我还有一个Python字典,其中包含每个功能的相关范围。键是功能名称,不同的值是键:
> dict_of_dose_ranges = {'A_dose': [1, 2, 3], 'B_dose': [40, 90], 'C_dose': [130,700]}
为了我的目的,我需要生成特定的组合(例如A_dose = 1, B_dose = 90, 和C_dose = 700),并根据这些设置从我的数据框中提取相关切片,然后从这个较小的子集中进行相关计算,并将结果保存到某个地方。
我需要对所有功能的所有可能组合(远不止这里的3个,而且未来可能会变化)执行此操作。
在这种情况下,我可以轻松地将它放入SkLearn的参数网格中,生成选项:
> from sklearn.grid_search import ParameterGrid> all_options = list(ParameterGrid(dict_of_dose_ranges)) > all_options
并得到:
[{'A_dose': 1, 'B_dose': 40, 'C_dose': 130}, {'A_dose': 1, 'B_dose': 40, 'C_dose': 700}, {'A_dose': 1, 'B_dose': 90, 'C_dose': 130}, {'A_dose': 1, 'B_dose': 90, 'C_dose': 700}, {'A_dose': 2, 'B_dose': 40, 'C_dose': 130}, {'A_dose': 2, 'B_dose': 40, 'C_dose': 700}, {'A_dose': 2, 'B_dose': 90, 'C_dose': 130}, {'A_dose': 2, 'B_dose': 90, 'C_dose': 700}, {'A_dose': 3, 'B_dose': 40, 'C_dose': 130}, {'A_dose': 3, 'B_dose': 40, 'C_dose': 700}, {'A_dose': 3, 'B_dose': 90, 'C_dose': 130}, {'A_dose': 3, 'B_dose': 90, 'C_dose': 700}]
这就是我遇到问题的地方:
问题#1) 我现在可以遍历all_options
,但我不确定如何从字典选项中(即{‘A_dose’: 1, ‘B_dose’: 40, ‘C_dose’: 130})选择我的dosage_df
,而不是明确指定它。
过去,我可以这样做:
dosage_df[(dosage_df.A_dose == 1) & (dosage_df.B_dose == 40) & (dosage_df.C_dose == 130)]First Score Last Score A_dose B_dose C_dose0 22 28 140 130
但现在我不确定在括号内放什么来动态切片…
dosage_df[?????]
问题#2) 当我实际输入我的完整功能字典及其各自的范围时,我会得到一个错误,因为它认为选项过多…
from sklearn.grid_search import ParameterGridall_options = list(ParameterGrid(dictionary_of_features_and_ranges)) all_options---------------------------------------------------------------------------OverflowError Traceback (most recent call last)<ipython-input-138-7b73d5e248f5> in <module>() 1 from sklearn.grid_search import ParameterGrid----> 2 all_options = list(ParameterGrid(dictionary_of_features_and_ranges)) 3 all_optionsOverflowError: long int too large to convert to int
我尝试了一些替代方法,包括使用双重while循环,来自这里的树/递归方法,来自这里的另一个递归方法,但没有成功…任何帮助都非常感激。
回答:
您可以使用itertools.product
生成所有可能的剂量组合,并使用DataFrame.query
进行选择:
from itertools import productfor dosage_comb in product(*dict_of_dose_ranges.values()): dosage_items = zip(dict_of_dose_ranges.keys(), dosage_comb) query_str = ' & '.join('{} == {}'.format(*x) for x in dosage_items) sub_df = dosage_df.query(query_str) # 执行操作...