Фильтрация информационного кадра панд по минимальным максимальным значениям - PullRequest
0 голосов
/ 14 марта 2019

У меня есть функция, которая имеет дополнительные kwargs (всего 8), основанные на минимальных и максимальных значениях, введенных пользователем.

Например, GR_min, GR_max, GR_N_min, GR_N_max, Hi_min, Hi_max и т. Д., Где столбцы данных: GR, GR_N, Hi и т. Д. *

Я бы хотел, чтобы кадр данных фильтровал по заданным минимальным и максимальным значениям, но если в вызове функции не указано одно или несколько значений для установки значений по умолчанию минимальных и максимальных значений, равных только минимальным и максимальным столбцы.

Например, некоторый псевдокод:

df = pd.DataFrame({'GR': [1, 2, 3, 4, 2, 3], 
'GR_N': [0.8, 0, 1, 0.6, 0.9, 1], 'Hi':[3, 6, 2, 5, 22, 7]})

Получает меня:

    GR  GR_N    Hi
0   1   0.8     3
1   2   0.0     6
2   3   1.0     2
3   4   0.6     5
4   2   0.9     22
5   3   1.0     7

Мне нужна функция, которая делает что-то вроде этого:

def picker(data, **kwargs):

      data_filtered = data[data['GR'].between(GR_min, GR_max) &
                         data['GR_N'].between(GR_N_min, GR_N_max) &
                         data['Hi'].between(Hi_min, Hi_max)]

      return data_filtered

с выводом после вызова:

picker(data=df, GR_min=2, GR_max=3, Hi_min=1, Hi_max=6)

    GR  GR_N    Hi
1   2   0.0     6
2   3   1.0     2

За исключением того, что вместо явного вызова каждого столбца кадра данных мы используем ** kwargs для фильтрации.

Есть ли способ сделать это?

Ответы [ 3 ]

1 голос
/ 14 марта 2019

DataFrame.query здесь может пригодиться, потому что он будет анализировать строку, содержащую условия.Поэтому будет достаточно построить строку условия из параметров ключевого слова.

Каждое отдельное условие может быть построено как: K<=val для параметра K_max=val и K>=val для параметра K_min=val.Для построения списка каждое отдельное условие должно быть заключено в круглые скобки (()), а затем соединено с &.

Код может быть:

def picker(data, **kwargs):
    def make_cond(k,v):
        if len(k)<5:
            raise(ValueError('Arg too short {}'.format(k)))
        if k.endswith('_min'):
            return '({}>={})'.format(k[:-4], v)
        elif k.endswith('_max'):
            return '({}<={})'.format(k[:-4], v)
        else:
            raise(ValueError('Unknow arg {}'.format(k)))
    strcond='&'.join((make_cond(k, v) for k,v in kwargs.items()))
    # print(strcond)     # uncomment for traces
    return data.query(strcond)
0 голосов
/ 14 марта 2019

Я немного озадачен этим, фильтрация по минимальным и максимальным значениям в столбцах просто не будет фильтровать, не так ли? Почему бы просто не фильтровать только по предоставленным аргументам? Несмотря на это, это звучит как случай для аргументов по умолчанию.

#create the DataFrame
df = pd.DataFrame({'GR': [1, 2, 3, 4, 2, 3], 
'GR_N': [0.8, 0, 1, 0.6, 0.9, 1], 'Hi':[3, 6, 2, 5, 22, 7]})

def picker(df, GR_min = None, GR_max = None, GR_N_min = None, GR_N_max = None,
           Hi_min = None, Hi_max = None): #use default arguments

           if GR_min == None:
               GR_min = df['GR'].min()
           if GR_max == None:
               GR_max = df['GR'].max()
           if GR_N_min == None:
               GR_N_min = df['GR_N'].min()
           if GR_N_max == None:
               GR_N_max == df['GR_N'].max()

           #filter the DataFrame with masks
           df_out = df.loc[(df['GR'] > GR_min) & (df['GR'] < GR_max) & 
                           (df['GR_N'] > GR_N_min) & (df['GR_N'] < GR_N_max)]
           return df_out
0 голосов
/ 14 марта 2019

У вас может быть словарь по умолчанию для ваших kwargs, указывающий min и max как -infinity и + infinity, а затем просто переопределите их с помощью пользовательского ввода. Примерно так:

import numpy as np
def picker(data, **kwargs):
    d = dict(GR_min=-np.inf, GR_max=np.inf) # ... etc
    kwargs = {**d, **kwargs}
    data_filtered = data[data['GR'].between(kwargs["GR_min"], kwargs["GR_max"])] # ... etc
    return data_filtered
...