Новый столбец на основе некоторых условий

Я хочу добавить новый столбец в соответствии с некоторыми условиями: где х и у одинаковые и год или год-1; если c = 1, новый столбец "c_new" = 1, иначе 0. Как мне это сделать?

import pandas as pd
data = {'x': [ 0, 300.1, 0, 300.1, 0, 300.1, 0, 300.1], 'y': [ 160.1, 400.1, 160.1, 400.1, 160.1, 400.1, 160.1, 400.1], 'a': [3, 4, 3, 4, 3, 4, 3, 4], 'c': [0, 0, 1, 0, 0, 0, 1, 0], 'year': [2000, 2000, 2001, 2001, 2002, 2002, 2003, 2003]}   
df = pd.DataFrame(data)
df
            
             x        y     a    c      year
        
        1   0.0     160.1   3   0.0     2000
        2   300.1   400.1   4   0.0     2000
        3   0.0     160.1   3   1.0     2001
        4   300.1   400.1   4   0.0     2001
        5   0.0     160.1   3   0.0     2002
        6   300.1   400.1   4   0.0     2002
        7   0.0     160.1   3   1.0     2003
        8   300.1   400.1   4   0.0     2003

Expected output:            
              x       y     a      c     year  c_new   
        
        1   0.0     160.1   3    0.0    2000   0.0       
        2   300.1   400.1   4    0.0    2000   0.0       
        2   0.0     160.1   3    1.0    2001   1.0       
        4   300.1   400.1   4    0.0    2001   0.0       
        5   0.0     160.1   3    0.0    2002   1.0        
        6   300.1   400.1   4    0.0    2002   0.0       
        7   0.0     160.1   3    1.0    2003   1.0       
        8   300.1   400.1   4    0.0    2003   0.0       

Я не уверен, что понимаю условия. Нет данных, где x и y совпадают, насколько я вижу. И это maximum year subtract 1 (or 2) или это year ending with 1 (or 2)?

S Rawson 10.04.2022 17:49

у вас всегда есть все промежуточные годы (2000, 2001, 2002, 2003…), или у вас могут быть пропущенные?

mozway 10.04.2022 17:52

Это означает, что при группировке по x, y и году (2022 г.); проверьте группу значений c по x, y и year-1 (2021) и проверьте группу значений c по x, y и year-2 (2020), если значение c равно 1 в любом случае, c_new = 1, иначе 0. @S Роусон

nurer 10.04.2022 18:11

У меня нет потерянных лет. @mozway

nurer 10.04.2022 18:13

@nurer, тогда вы можете проверить мой ответ, я думаю, это то, что вы хотите

mozway 10.04.2022 18:23
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что у вас есть все годы, вы можете использовать сдвинутый скользящий максимум:

N = 2 # number of previous years to consider
df['c_new'] = (df
 .groupby(['x', 'y'])
 ['c'].apply(lambda x: x.shift().rolling(N, min_periods=1).max())
)

выход:

       x      y  a  c  year  c_new
0    0.0  160.1  3  0  2000    NaN
1  300.1  400.1  4  0  2000    NaN
2    0.0  160.1  3  1  2001    0.0
3  300.1  400.1  4  0  2001    0.0
4    0.0  160.1  3  0  2002    1.0
5  300.1  400.1  4  0  2002    0.0
6    0.0  160.1  3  1  2003    1.0
7  300.1  400.1  4  0  2003    0.0

NB. будьте осторожны с группировкой по поплавкам. Убедитесь, что они округлены, чтобы близкие числа не образовывали разные группы.

обновление: год и год-1
N = 2 # number of previous years to consider
df['c_new'] = (df
 .groupby(['x', 'y'])
 ['c'].rolling(N, min_periods=1).max().droplevel(['x', 'y'])
)

выход:

       x      y  a  c  year  c_new
0    0.0  160.1  3  0  2000    0.0
1  300.1  400.1  4  0  2000    0.0
2    0.0  160.1  3  1  2001    1.0
3  300.1  400.1  4  0  2001    0.0
4    0.0  160.1  3  0  2002    1.0
5  300.1  400.1  4  0  2002    0.0
6    0.0  160.1  3  1  2003    1.0
7  300.1  400.1  4  0  2003    0.0

Спасибо @mozway. Оно работает. Но мне жаль, что я ошибся в своем вопросе. Я исправил свой вопрос. Он должен проверить значение c для того же года и предыдущего года. В таком случае, как я могу это сделать?

nurer 10.04.2022 19:06

@nurer тогда еще проще, простой groupby+rolling.max, смотрите обновление ;)

mozway 10.04.2022 19:13

Другие вопросы по теме