Многократная проверка на пустой фрейм данных - PullRequest
0 голосов
/ 30 октября 2018

У меня есть ситуация, когда мне нужно переместить кадр данных в коде, только если он не пустой. Иллюстрированный ниже:

----- Filter 1 -------
Check if df.empty then return emptydf
else
----- Filter 2 ------
Check if df.empty then return emptydf
else
----- Filter 3 ------
return df

Код для выше написано, как показано ниже (только часть кода):

def filter_df(df):
    df = df[df.somecolumn > 2].copy()

    if df.empty:
        return df

    df = df[df.someother == 2].copy()

    if df.empty:
        return df

    df = df[df.all <= 10].copy()

    return df

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

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Повторное подмножество вашего фрейма данных стоит дорого. Повторное копирование вашего фрейма данных также может быть дорогостоящим. Это также дорого предварительно рассчитать большое количество логических масок. Хитрая часть находит способ применить маски лениво в петле for.

Хотя приведенное ниже функциональное решение может показаться некрасивым, оно решает вышеуказанные проблемы. Идея состоит в том, чтобы итеративно комбинировать булеву маску с агрегированной маской. Проверьте в своем цикле, имеет ли ваша mask все значения False, а не пустой ли фрейм данных. Примените совокупную маску один раз в конце вашей логики:

from operator import methodcaller

def filter_df(df):

    masks = [('somecolumn', 'gt', 2),
             ('someother', 'eq', 2),
             ('all', 'le', 10)]

    agg_mask = np.ones(len(df.index)).astype(bool)  # "all True" mask

    for col, op, val in masks:

        mask = methodcaller(op, val)(df[col])
        agg_mask = agg_mask & mask

        if not agg_mask.any():
            return df[agg_mask]

    return df[agg_mask]

Примечание для этого решения Операторы сравнения рядов, такие как >, ==, <=, имеют функциональные эквиваленты pd.Series.gt, pd.Series.eq, pd.Series.le.

0 голосов
/ 30 октября 2018

Вы можете использовать функцию и вызывать ее после самого фильтра

def check_empty(df):
    if df.empty:
       return df

df = df[df.somecolumn > 2].copy()

check_empty(df)

df = df[df.someother == 2].copy()

check_empty(df)

df = df[df.all <= 10].copy()

return df 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...