Замените все значения до последнего ненулевого значения в столбце на 0

#python #pandas #numpy #dataframe

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

Вопрос:

У меня есть 2 фрейма данных с одинаковым индексом и формой, скажем, A и B. Моя цель — вычислить сумму каждой строки в df_B, но если для любых строк ниже последнего ненулевого значения в df_A, эти соответствующие строки не будут учитываться в сумме в df_B. Это пример, показывающий, что я делаю:

 df_A = pd.DataFrame({'col1': [1,1,0,1,0], 'col2': [1,0,0,0,0]})
df_B = pd.DataFrame({'col1': [2,2,2,2,2], 'col2': [2,2,2,2,2]})

OR:

df_A:
col1|col2
1.  |1.  
1.  |0
0.  |0
1.  |0
0.  |0

df_B:
col1|col2
2.  |2.  
2.  |2
2.  |2
2.  |2
2.  |2
  

Результат, который я хочу получить, выглядит следующим образом:

 df_B:
col1|col2
2.  |2.  
2.  |0
2.  |0
2.  |0
0.  |0
  

Для каждого столбца в df_A, начиная с последнего ненулевого значения, значения после этой позиции в df_B будут равны 0.

Вот что я пробовал и застрял:

  1. получите позицию индекса последнего ненулевого значения в каждом столбце, so ([3,1]) для 2 col в df_A.
 row_ix = df_A.shape[0]-df_A.ne(0).values[::-1].argmax(0)-1
  
  1. для каждого столбца установите значения перед позицией row_ix равными 0 (это по сути противоположно моему решению, но я могу изменить это, чтобы получить свой ответ)
 for i in row_ix:
    for col in df.columns:
        df[col].values[:row_ix[i]] = 0
  

Это правильный подход или есть лучший способ сделать это?
Спасибо!

Ответ №1:

Попробуйте это :

    def zero_index(df, column_name):
       indexer = df.index[df[column_name].eq(0)]
        # checks if the values are consecutive
        if np.any(np.diff(indexer) > 1):
            return indexer[-1]
        return indexer[0]


df_B.loc[zero_index(df_A, "col1") :, "col1"] = 0
df_B.loc[zero_index(df_A, "col2") :, "col2"] = 0

df_B


   col1 col2
0   2   2
1   2   0
2   2   0
3   2   0
4   0   0
  

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

1. Да, это отлично работает. Спасибо! Я застрял на нем примерно на час.