Панды: обрезать строки в конце группы фреймов в зависимости от условия - PullRequest
0 голосов
/ 09 февраля 2019

Допустим, у меня есть следующий фрейм данных:

df = pd.DataFrame({"id": [1, 1, 1, 2, 2, 2, 3, 3, 3, 3], "date": [pd.Timestamp(2002, 2, 2), pd.Timestamp(2003, 3, 3), pd.Timestamp(2004, 4, 4), pd.Timestamp(2005, 5, 5), pd.Timestamp(2006, 6, 6), pd.Timestamp(2007, 7, 7), pd.Timestamp(2008, 8, 8), pd.Timestamp(2009, 9, 9), pd.Timestamp(2010, 10, 10), pd.Timestamp(2011, 11, 11)], "numeric": [0.9, 0.4, 0.2, 0.6, np.nan, 0.8, 0.7, np.nan, np.nan, 0.5], "nominal": [0, 1, 0, 1, 0, 0, 0, 1, 1, 1]})

Чего я хочу добиться - это обрезать строки в конце каждой группы (при условии, что строки сгруппированы по id)так, что строки будут удаляться до тех пор, пока для столбца numeric не появится значение non-nan.Кроме того, последняя строка для каждой группы всегда будет иметь значение non-nan для столбца numeric, а последнюю строку всегда следует удалять.Итак, результирующий фрейм данных:

result_df = pd.DataFrame({"id": [1, 1, 2, 3], "date": [pd.Timestamp(2002, 2, 2), pd.Timestamp(2003, 3, 3), pd.Timestamp(2005, 5, 5), pd.Timestamp(2008, 8, 8)], "numeric": [0.9, 0.4, 0.6, 0.7], "nominal": [0, 1, 1, 0]})

Дополнительные пояснения о том, как мы получаем результирующий фрейм данных:

  • Для id == 1 удаляется только последняя строкапоскольку в строке перед последней имеется значение для столбца numeric.
  • Для id == 2 последние две строки удаляются, поскольку последняя строка по умолчанию удаляется строкой, предшествующей последнейa nan value.
  • Для id == 3 последние три строки удаляются, поскольку последняя строка удаляется по умолчанию, а первое значение non-nan находится в четвертой строке, считая снизу.

Более того, в настоящее время я делаю следующее:

df.groupby("id", as_index=False).apply(lambda x: x.iloc[:-1]).reset_index(drop=True)

Однако это удаляет только последнюю строку для каждой группы, и я хочу удалить последние N строки на основе объясненного условия.выше.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и с нетерпением ждем ваших ответов!

1 Ответ

0 голосов
/ 09 февраля 2019

Для конкретного примера, который вы опубликовали, просто удалив NaN перед группировкой, добьемся цели:

df = df.dropna().groupby('id').apply(lambda x: x.iloc[:-1]).reset_index(drop=True)

df
Out[58]: 
   id       date  numeric  nominal
0   1 2002-02-02      0.9        0
1   1 2003-03-03      0.4        1
2   2 2005-05-05      0.6        1
3   3 2008-08-08      0.7        0

Если у вас есть несмежные NaN и вы хотите удалить только последний блок NaN:

def strip_rows(X):    
    X = X.iloc[:-1, :]
    while pd.isna(X.iloc[-1, 2]):        
        X = X.iloc[:-1, :]
    return X

df_1 = pd.DataFrame({"id": [1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3],
                   "date": [pd.Timestamp(2002, 2, 2),
                            pd.Timestamp(2003, 3, 3), 
                            pd.Timestamp(2004, 4, 4), 
                            pd.Timestamp(2005, 5, 5), 
                            pd.Timestamp(2006, 6, 6),
                            pd.Timestamp(2007, 7, 7),
                            pd.Timestamp(2008, 8, 8),
                            pd.Timestamp(2009, 9, 9),
                            pd.Timestamp(2010, 10, 10), 
                            pd.Timestamp(2011, 11, 11),
                            pd.Timestamp(2011, 12, 12),
                            pd.Timestamp(2012, 1, 1)],
                    "numeric": [0.9, 0.4, 0.2, 0.6, np.nan, 0.8, 0.7, np.nan, np.nan, 0.5, np.nan, 0.3],
                    "nominal": [0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1]})

df_2 = df_1.groupby('id').apply(strip_rows).reset_index(drop=True)

df_1
Out[151]: 
    id       date  numeric  nominal
0    1 2002-02-02      0.9        0
1    1 2003-03-03      0.4        1
2    1 2004-04-04      0.2        0
3    2 2005-05-05      0.6        1
4    2 2006-06-06      NaN        0
5    2 2007-07-07      0.8        0
6    3 2008-08-08      0.7        0
7    3 2009-09-09      NaN        1
8    3 2010-10-10      NaN        1
9    3 2011-11-11      0.5        1
10   3 2011-12-12      NaN        0
11   3 2012-01-01      0.3        1

df_2
Out[152]: 
   id       date  numeric  nominal
0   1 2002-02-02      0.9        0
1   1 2003-03-03      0.4        1
2   2 2005-05-05      0.6        1
3   3 2008-08-08      0.7        0
4   3 2009-09-09      NaN        1
5   3 2010-10-10      NaN        1
6   3 2011-11-11      0.5        1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...