Я пытаюсь изменить значения данного столбца в моем наборе данных на основе значений вокруг данной ячейки. Рассмотрим следующие данные:
Data = {'Col1': [5593 , 5114 , 6803 , 2175 , 2175] , 'Col2': [2879 , 1176 , 7114 , 8677 , 0]}
df = pd.DataFrame(data = Data)
df.head()
Col1 Col2
0 5593 2879
1 5114 1176
2 6803 7114
3 2175 8677
4 2175 0
Я создаю новый столбец для хранения новых значений:
Data['Col3'] = Data['Col2']
Я хочу сделать функцию применения - лямбда, которая делает следующее: Если Col3 равен нулю, а предыдущее значение Col1 равно текущему значению Col1, то есть: (x.shift(-2, -1) == x.shift(-2, 0), то фактическое значение Col3 должно быть предыдущее значение Col2, т. е. x.shift(-1 , -1), иначе значение Col3 не должно меняться.
Я пробовал что-то вроде следующего (псевдокод):
df['Col3'] = df['Col3'].apply(lambda x: x.shift(-1 , -1) if (x == 0 and x.shift(-2 , -1) == x.shift(-2, 0)) else x)
Для этого конкретного подмножества моих данных это должно выглядеть следующим образом:
Col1 Col2 Col3
0 5593 2879 2879
1 5114 1176 1176
2 6803 7114 7114
3 2175 8677 8677
4 2175 0 8677
Я не уверен, что сдвиг является правильным методом для использования (серия содержит NaN), но, надеюсь, идея ясна.
Мой реальный набор данных очень большой, поэтому я хочу, чтобы операции выполнялись хорошо со многими строками.






IIUC, вы можете использовать np.where со сдвинутыми столбцами:
df['Col3'] = np.where(df['Col1'].shift().eq(df['Col1']), df['Col2'].shift(), df['Col2'])
print(df)
Выход
Col1 Col2 Col3
0 5593 2879 2879.0
1 5114 1176 1176.0
2 6803 7114 7114.0
3 2175 8677 8677.0
4 2175 0 8677.0
Ниже пошагово, объяснение с комментариями:
# create a mask, where is True if the consecutive values in Col1 are equal
mask = df['Col1'].shift().eq(df['Col1'])
# choose between the shifted Col2 (the previous value) and Col2 using the mask
df['Col3'] = np.where(mask, df['Col2'].shift(), df['Col2'])
print(df)
@ Amby95 Не могли бы вы добавить небольшой пример, когда это не работает?
Если бы вы переключили индекс 3 и 4 в первом выводе, у вас был бы именно тот случай, о котором я говорю. Затем он все равно должен проверить, находится ли одно и то же значение в строке выше или ниже, и если это так, то должна быть выполнена та же процедура.
Это прекрасно работает, если значение появляется в первой строке! Есть ли способ расширить код так, чтобы он также проверял те же условия, но и для строки ниже? В моей терминологии это будет shift(1 , 1)