Питон |Панды сбрасывают значения в нескольких интервалах - PullRequest
0 голосов
/ 31 января 2019

У меня есть набор данных, который на самом деле не сбалансирован.Следовательно, я хочу отбросить значения в определенных диапазонах так, чтобы в каждом диапазоне у меня оставалось только меньше наблюдений, чем заданное число cutoff.

Я приказываю объяснить, что я имею в виду, я покажу один пример (значения в столбце b являются числами с плавающей запятой)

  a b
0 1 0
1 7 0
2 9 5
3 3 9
4 5 6 

Я хочу найти в столбце b конкретные диапазоны, например ranges = np.array([0, 2, 4, 6, 8, 10]) с учетом cutoff = 1 (может быть любым указанным целым числом).Например, значение 0 в первой строке лежит в интервале [0,2) (2 не включено), а во второй строке также содержится значение из этого интервала.Поскольку обрезание равно единице, в этом интервале может находиться только одно значение b.Следовательно, вторая строка отбрасывается (было бы здорово, если бы строки не удалялись последовательно, а скорее недетерминированно), и мы получаем следующий сокращенный кадр данных.

  a b
0 1 0
2 9 5
3 3 9
4 5 6 

1 Ответ

0 голосов
/ 31 января 2019

Вы можете использовать pd.cut, чтобы связать значения в b в соответствии с ranges и удалить те, которые duplicated:

ranges = np.array([0, 2, 4, 6, 8, 10])
df[~(pd.cut(df.b, ranges, include_lowest=True, right=False)).duplicated()]

   a  b
0  1  0
2  9  5
3  3  9
4  5  6

Где:

pd.cut(df.b, ranges, include_lowest=True, right=False)

0     [0, 2)
1     [0, 2)
2     [4, 6)
3    [8, 10)
4     [6, 8)
Name: b, dtype: category

Обновление

Если вы хотите использовать конкретную обрезку разрешенных дублированных значений, вы можете сгруппировать по интервалам, возвращаемым pd.cutи выберите первые n значения, которые дублируются с помощью [head], чтобы выбрать первые n строки, принадлежащие к тому же интервалу.

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

print(df)
   a  b
0  1  0
1  7  0
2  7  0
3  9  5
4  3  9
5  5  6

cuttoff = 2
g = pd.cut(df.b, ranges, include_lowest=True, right=False)
df.groupby(g).head(cuttoff)

   a  b
0  1  0
1  7  0
3  9  5
4  3  9
5  5  6
...