Как сдвинуть элементы столбца pandas для заданного индекса на основе условия?

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Я недавно начал использовать python и pandas, пожалуйста, потерпите меня в этом. У меня есть два столбца (A, B) данных (dataframe), которые должны быть расположены в определенной последовательности на основе определенного отношения между двумя столбцами (скажем, элементы столбца A должны быть меньше, чем элементы столбца B для данного индекса), если отношение не выполняется, данные должны сдвигаться (только для A) на строку, начинающуюся с индекса, где условие не выполняется по всей длине столбца. И его следует заменить на NaN, где это условие не выполняется.

Я попробовал функцию shift (1). Это работает, только если первый элемент не соответствует условию, но если есть какой-либо другой элемент или несколько элементов не соответствуют критериям, это создает несколько NAN в начале столбца A, а не в том месте, где критерии не выполняются.

 mdata1 = [[3,2],[5,4],[8,6],[10,7],[float('NaN'),9],[float('NaN'),11]]
mdf1 = pd.DataFrame(mdata1,columns=['A','B'])

for xt in range (0,len(mdf1)):
    if mdf1.A[xt]>mdf1.B[xt]:
        mdf1['A'] = mdf1['A'].shift(1)
  

Фактический результат

 A   B
NaN 2
NaN 4
3.0 6
5.0 7
8.0 9
10.0    11
  

Ожидаемый результат

 A   B
NaN 2
3.0 4
5.0 6
NaN 7
8.0 9
10.0    11
  

Ответ №1:

Я не понимаю, что именно вы хотите сделать. но, просто изменяя ваш код, я получаю ожидаемые результаты:

 for xt in range (0,len(mdf1)):
if mdf1.A[xt]>mdf1.B[xt]:
    mdf1.loc[xt:,'A'] = mdf1[xt:]['A'].shift(1)
  

shift (1) сдвигает весь столбец / фрейм данных на одну строку, таким образом, вам нужно начать смещение с индекса, в котором вы находитесь, чтобы получить то, что вы хотите.

Комментарии:

1. Спасибо, это именно то, чего мне не хватало, начиная операцию сдвига (1) с требуемого индекса. Это связано с мониторингом области на основе двух датчиков, где данные датчика 1 всегда меньше, чем у датчика 2, но для этого оба датчика должны сообщать данные. Иногда датчик 1 этого не делает, и это создает проблему при анализе post. Это намного сложнее, но это самое простое объяснение, которое я могу дать.

Ответ №2:

Я бы сделал merge_asof из исходного столбца dataframe B в dataframe, содержащий только значения, отличные от NaN, из столбца A. Удаление дубликатов в новом столбце даст вам ожидаемый результат:

 tmp = pd.merge_asof(mdf1, pd.DataFrame(mdf1.A.dropna().astype(np.int64)),
                    left_on='B', right_on='A', suffixes=('_x', ''))['A']

mdf1['A'] = np.where(tmp.duplicated(), np.nan, tmp)