2016-09-07 4 views
1

TLDR: Как перебирать все параметры нескольких столбцов в кадре данных pandas без указания столбцов или их значений явно?Итерация по нескольким столбцам в Pandas DF и динамическая резка

Длинная версия: У меня есть рамка данных pandas, которая выглядит так, только она имеет намного больше возможностей или комбинаций лекарственной дозы, чем здесь. Вместо всего 3 типов функций, он может иметь что-то вроде 70 ...:

> 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 

вместе с моим фреймом данных, у меня есть словарь питона с соответствующими диапазонами для каждой функции. Клавиши имена элементов, и различные значения, которые может принимать ключи:

> 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 

Я пробовал ряд альтернативных подходов, в том числе используя двойные циклы, tree/recursion method from here, еще один recursion method from here, но он не собирался ... Любая помощь очень ценится.

ответ

2

Вы можете использовать itertools.product генерировать все возможные комбинации лекарственных и 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... 
0

Как использовать базовый массив 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]) 
+0

вы смогли получить эту работу? Я получил ошибку: IndexError: только целые числа, срезы (':'), ellipsis ('...'), numpy.newaxis ('None') и целые или логические массивы являются допустимыми индексами – Afflatus

+0

Я немного отредактировал код, чтобы исправить ошибку 'arr [:, item [0]]' и поменять arthmetic для побитовых операторов и добавить значения примера, чтобы он был скопирован/готов к использованию. Как и сейчас, для меня это нормально. – jadsq

+0

Я думаю, что это работает только для вас. B/c столбцы dosage_df и dict_of_dose_ranges имеют ключи, которые являются целыми числами. – Afflatus

Смежные вопросы