Панды: заменить / изменить повторяющиеся значения в пределах временного диапазона - PullRequest
0 голосов
/ 05 октября 2018

У меня есть фрейм данных pandas, где я пытаюсь заменить / изменить дублирующиеся значения на 0 (не хочу удалять значения) в течение определенного диапазона дней.

Итак, в приведенном ниже примере я хочу заменить повторяющиеся значения во всех столбцах на 0 в диапазоне, скажем, 3 (число можно изменить) дней.Желаемый результат также приведен ниже

              A   B  C

01-01-2011   2   10  0
01-02-2011   2   12  2
01-03-2011   2   10  0
01-04-2011   3   11  3
01-05-2011   5   15  0
01-06-2011   5   23  1
01-07-2011   4   21  4
01-08-2011   2   21  5
01-09-2011   1   11  0

Таким образом, вывод должен выглядеть следующим образом:

              A   B  C

01-01-2011   2   10  0
01-02-2011   0   12  2
01-03-2011   0   0   0
01-04-2011   3   11  3
01-05-2011   5   15  0
01-06-2011   0   23  1
01-07-2011   4   21  4
01-08-2011   2   0   5
01-09-2011   1   11  0

Любая помощь будет оценена.

Ответы [ 2 ]

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

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

def set_zeros(g):
    g.values[1:] = 0
    return g

for c in df.columns:
    df[c] = df.groupby([c, pd.Grouper(freq='3D')], as_index=False)[c].transform(set_zeros)

Эта пользовательская функция может применяться к каждой группе, которая определяется диапазоном времени (freq='3D') и равными значениями столбца в течение этого периода.Поскольку столбцы обычно имеют одинаковые значения в разных строках, это необходимо сделать для каждого столбца в цикле.

Измените freq на 5D, 10D или 20D для других ваших соображений.
Подробное описание того, как определить период времени, см. http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases

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

Вы можете использовать df.shift () для этого, чтобы посмотреть значение из строки вверх или вниз (или нескольких строк, указанных числом x в .shift (x)).

Вы можете использовать это в сочетании с .loc для выбора всех строк, которые имеют значение, идентичное значению 2 строк выше, а затем заменить его на 0.

Что-то вроде этого должно работать: (изменил код, чтобы сделать его гибким для бесконечного количества столбцов и гибким для количества дней)

numberOfDays = 3 # number of days to compare

for col in df.columns:
    for x in range(1, numberOfDays):
        df.loc[df[col] == df[col].shift(x), col] = 0

print df

Это дает мне вывод:

            A   B  C
date
01-01-2011  2  10  0
01-02-2011  0  12  2
01-03-2011  0   0  0
01-04-2011  3  11  3
01-05-2011  5  15  0
01-06-2011  0  23  1
01-07-2011  4  21  4
01-08-2011  2   0  5
01-09-2011  1  11  0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...