在 Pandas DF 中遍历多列并动态切片
Iterating across multiple columns in Pandas DF and slicing dynamically
TLDR: 如何在不明确指定列或其值的情况下遍历 pandas 数据框中多列的所有选项?
长版: 我有一个看起来像这样的 pandas 数据框,只是它的特征或药物剂量组合比这里列出的要多得多。而不是只有 3 种类型的功能,它可能有 70...:[=21=]
> dosage_df
First Score Last Score A_dose B_dose C_dose
22 28 1 40 130
55 11 2 40 130
15 72 3 40 130
42 67 1 90 130
90 74 2 90 130
87 89 3 90 130
14 43 1 40 700
12 61 2 40 700
41 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
,但我不确定现在如何 SELECT 从我的 dosage_df
来自每个字典选项(即 {'A_dose': 1, 'B_dose': 40, 'C_dose': 130})而不明确地做。
过去,我可以这样做:
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_dose
0 22 28 140 130
但现在我不确定在括号内放什么来动态切片...
dosage_df[?????]
问题 #2) 当我实际输入我的完整特征字典及其各自的范围时,我得到一个错误,因为它认为它有太多选项......
from sklearn.grid_search import ParameterGrid
all_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_options
OverflowError: long int too large to convert to int
我尝试了多种替代方法,包括使用双 while 循环,一个 tree / recursion method from here, another recursion method from here,但它们没有结合在一起....非常感谢任何帮助。
如何使用底层 numpy 数组和一些布尔逻辑来构建一个只包含您想要的行的数组?
dosage_df = pd.DataFrame((np.random.rand(40000,10)*100).astype(np.int))
dict_of_dose_ranges={3:[10,11,12,13,15,20],4:[20,22,23,24]}
#combined_doses will be bool array that will select all the lines that match the wanted combinations of doses
combined_doses=np.ones(dosage_df.shape[0]).astype(np.bool)
for item in dict_of_dose_ranges.items():
#item[0] is the kind of dose
#item[1] are the values of that kind of dose
next_dose=np.zeros(dosage_df.shape[0]).astype(np.bool)
#we then iterate over the wanted values
for value in item[1]:
# we select and "logical or" all lines matching the values
next_dose|=(dosage_df[item[0]] == value)
# we "logical and" all the kinds of dose
combined_doses&=next_dose
print(dosage_df[combined_doses])
您可以使用itertools.product
to generate all possible dosage combinations, and DataFrame.query
进行选择:
from itertools import product
for 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)
# Do Stuff...
TLDR: 如何在不明确指定列或其值的情况下遍历 pandas 数据框中多列的所有选项?
长版: 我有一个看起来像这样的 pandas 数据框,只是它的特征或药物剂量组合比这里列出的要多得多。而不是只有 3 种类型的功能,它可能有 70...:[=21=]
> dosage_df
First Score Last Score A_dose B_dose C_dose
22 28 1 40 130
55 11 2 40 130
15 72 3 40 130
42 67 1 90 130
90 74 2 90 130
87 89 3 90 130
14 43 1 40 700
12 61 2 40 700
41 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
,但我不确定现在如何 SELECT 从我的 dosage_df
来自每个字典选项(即 {'A_dose': 1, 'B_dose': 40, 'C_dose': 130})而不明确地做。
过去,我可以这样做:
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_dose
0 22 28 140 130
但现在我不确定在括号内放什么来动态切片...
dosage_df[?????]
问题 #2) 当我实际输入我的完整特征字典及其各自的范围时,我得到一个错误,因为它认为它有太多选项......
from sklearn.grid_search import ParameterGrid
all_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_options
OverflowError: long int too large to convert to int
我尝试了多种替代方法,包括使用双 while 循环,一个 tree / recursion method from here, another recursion method from here,但它们没有结合在一起....非常感谢任何帮助。
如何使用底层 numpy 数组和一些布尔逻辑来构建一个只包含您想要的行的数组?
dosage_df = pd.DataFrame((np.random.rand(40000,10)*100).astype(np.int))
dict_of_dose_ranges={3:[10,11,12,13,15,20],4:[20,22,23,24]}
#combined_doses will be bool array that will select all the lines that match the wanted combinations of doses
combined_doses=np.ones(dosage_df.shape[0]).astype(np.bool)
for item in dict_of_dose_ranges.items():
#item[0] is the kind of dose
#item[1] are the values of that kind of dose
next_dose=np.zeros(dosage_df.shape[0]).astype(np.bool)
#we then iterate over the wanted values
for value in item[1]:
# we select and "logical or" all lines matching the values
next_dose|=(dosage_df[item[0]] == value)
# we "logical and" all the kinds of dose
combined_doses&=next_dose
print(dosage_df[combined_doses])
您可以使用itertools.product
to generate all possible dosage combinations, and DataFrame.query
进行选择:
from itertools import product
for 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)
# Do Stuff...