Я хочу добавить новый столбец в соответствии с некоторыми условиями: где х и у одинаковые и год или год-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
у вас всегда есть все промежуточные годы (2000, 2001, 2002, 2003…), или у вас могут быть пропущенные?
Это означает, что при группировке по x, y и году (2022 г.); проверьте группу значений c по x, y и year-1 (2021) и проверьте группу значений c по x, y и year-2 (2020), если значение c равно 1 в любом случае, c_new = 1, иначе 0. @S Роусон
У меня нет потерянных лет. @mozway
@nurer, тогда вы можете проверить мой ответ, я думаю, это то, что вы хотите
Предполагая, что у вас есть все годы, вы можете использовать сдвинутый скользящий максимум:
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. будьте осторожны с группировкой по поплавкам. Убедитесь, что они округлены, чтобы близкие числа не образовывали разные группы.
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 тогда еще проще, простой groupby
+rolling.max
, смотрите обновление ;)
Я не уверен, что понимаю условия. Нет данных, где
x
иy
совпадают, насколько я вижу. И этоmaximum year subtract 1 (or 2)
или этоyear ending with 1 (or 2)
?