2016-10-26 3 views
4

Я хотел бы получить счет для # из предыдущих 5 значений в df ['A'], которые являются текущим значением в df ['A'] & также> = df2 ['A']. Я стараюсь избегать цикла для каждой строки и столбцов, потому что я хотел бы применить это к большему набору данных.Как я могу реплицировать excel COUNTIFS в python/pandas?

Учитывая это ...

list1 = [[21,101],[22,110],[25,113],[24,112],[21,109],[28,108],[30,102],[26,106],[25,111],[24,110]] 
df = pd.DataFrame(list1,index=pd.date_range('2000-1-1',periods=10, freq='D'), columns=list('AB')) 
df2 = pd.DataFrame(df * (1-.05)) 

Я хотел бы вернуть это (решить в Excel с COUNTIFS) ...

enter image description here

Линия ниже достигает первой части (спасибо Александр), и Divakar и DSM также взвесили ранее (here и here).

df3 = pd.DataFrame(df.rolling(center=False,window=6).apply(lambda rollwin: sum((rollwin[:-1] < rollwin[-1])))) 

Но я не могу добавить сравнение к df2. Пожалуйста помоги.

ПОСЛЕДУЮЩИЕ на 10/27/16:

Как бы написать лямбда выше, в качестве стандартной функции?

10/28/16:

Ниже, с Col «А» от оба ДФА и df2, я пытаюсь подсчитать, сколько из предыдущих 5 значений из ДФА [ «A»] падение между текущий df2 ['A'] и df ['A']. Говоря иначе, сколько из каждой оранжевой коробки падает между желтым диапазоном низких частот?

enter image description here

UPDATE: разные данные песни1 производит неправильный DF3 ...

list1 = [[21,101],[22,110],[25,113],[24,112],[21,109],[26,108],[25,102],[26,106],[25,111],[22,110]] 
df = pd.DataFrame(list1,index=pd.date_range('2000-1-1',periods=10, freq='D'), columns=list('AB')) 
df2 = pd.DataFrame(df * (1-.05)) 

df3 = pd.DataFrame(
    df.rolling(center=False,window=6).apply(
      lambda rollwin: pd.Series(rollwin[:-1]).between(rollwin[-1]*0.95,rollwin[-1]).sum())) 

df 
Out[9]: 
      A B 
2000-01-01 21 101 
2000-01-02 22 110 
2000-01-03 25 113 
2000-01-04 24 112 
2000-01-05 21 109 
2000-01-06 26 108 
2000-01-07 25 102 
2000-01-08 26 106 
2000-01-09 25 111 
2000-01-10 22 110 


df3 
Out[8]: 
       A B 
2000-01-01 NaN NaN 
2000-01-02 NaN NaN 
2000-01-03 NaN NaN 
2000-01-04 NaN NaN 
2000-01-05 NaN NaN 
2000-01-06 1.0 0.0 
2000-01-07 2.0 0.0 
2000-01-08 3.0 1.0 
2000-01-09 2.0 3.0 
2000-01-10 1.0 3.0 

EXCEL Примеры (11/14): см ниже, пытаясь подсчитать, сколько чисел в синей коробке падения между диапазон выделен оранжевым цветом.

enter image description here

+2

Ваш ' df2' не воспроизводится. 'df_data' здесь не определен. – Psidom

+0

фиксированный Psidom. Благодарю. – MJS

+0

Будем ли мы убирать этот вопрос и отвечать? – Dickster

ответ

1
list1 = [[21,50,101],[22,52,110],[25,49,113],[24,49,112],[21,55,109],[28,54,108],[30,57,102],[26,56,106],[25,58,111],[24,60,110]] 
df = pd.DataFrame(list1,index=pd.date_range('2000-1-1',periods=10, freq='D'), columns=list('ABC')) 

print df 

Я считаю, это соответствует ваш новый снимок экрана "Исходные данные".

   A B C 
2000-01-01 21 50 101 
2000-01-02 22 52 110 
2000-01-03 25 49 113 
2000-01-04 24 49 112 
2000-01-05 21 55 109 
2000-01-06 28 54 108 
2000-01-07 30 57 102 
2000-01-08 26 56 106 
2000-01-09 25 58 111 
2000-01-10 24 60 110 

enter image description here

и ту же функцию:

print pd.DataFrame(
      df.rolling(center=False,window=6). 
       apply(lambda rollwin: pd.Series(rollwin[:-1]). 
        between(rollwin[-1]*0.95,rollwin[-1]).sum())) 

дает ваш желаемый результат "Желаемый результат":

   A B C 
2000-01-01 nan nan nan 
2000-01-02 nan nan nan 
2000-01-03 nan nan nan 
2000-01-04 nan nan nan 
2000-01-05 nan nan nan 
2000-01-06 0 1 0 
2000-01-07 0 1 0 
2000-01-08 1 2 1 
2000-01-09 1 2 3 
2000-01-10 0 2 3 

enter image description here

+0

он работает. Спасибо большое. переключение между включительно = True/False важно. – MJS

2
list1 = [[21,101],[22,110],[25,113],[24,112],[21,109],[28,108],[30,102],[26,106],[25,111],[24,110]] 
df = pd.DataFrame(list1,index=pd.date_range('2000-1-1',periods=10, freq='D'), columns=list('AB')) 
df2 = pd.DataFrame(df * (1-.05)) 


window = 6 
results = [] 
for i in range (len(df)-window+1): 
    slice_df1 = df.iloc[i:i + window] 
    slice_df2 = df2.iloc[i:i + window] 
    compare1 = slice_df1['A'].iloc[-1] 
    compare2 = slice_df2['A'].iloc[-1] 
    a= slice_df1.iloc[:-1]['A'].between(compare2,compare1) # series have a between metho 
    results.append(a.sum()) 

df_res = pd.DataFrame(data = results , index = df.index[window-1:] , columns = ['countifs']) 
df_res = df_res.reindex(df.index,fill_value=0.0) 
print df_res 

which yields: 

      countifs 
2000-01-01 0.0000 
2000-01-02 0.0000 
2000-01-03 0.0000 
2000-01-04 0.0000 
2000-01-05 0.0000 
2000-01-06 0.0000 
2000-01-07 0.0000 
2000-01-08 1.0000 
2000-01-09 1.0000 
2000-01-10 0.0000 

НО

Наблюдения есть логическая связь между верхней и нижней границей, стоимостью и стоимостью - 5%. Тогда это, возможно, будет тем, что вы хотите.

df3 = pd.DataFrame(
     df.rolling(center=False,window=6).apply(
      lambda rollwin: sum(np.logical_and(
            rollwin[-1]*0.95 <= rollwin[:-1] 
            ,rollwin[:-1] < rollwin[-1]) 
           ))) 

и если вы предпочитаете подход pd.Series.between():

df3 = pd.DataFrame(
    df.rolling(center=False,window=6).apply(
      lambda rollwin: pd.Series(rollwin[:-1]).between(rollwin[-1]*0.95,rollwin[-1]).sum())) 
+0

спасибо Дикстер, очень ценю ваш вклад. Пока я работаю над вашим решением, я добавил немного цвета к моему вопросу выше - вероятно, не спросил достаточно ясно. – MJS

+0

ha great - это гораздо более ясный вопрос сейчас! – Dickster

+0

работает отлично, спасибо еще раз. Я считаю, что подход .between() превосходит первый метод. я собираюсь задать вопрос в качестве нового вопроса. – MJS

 Смежные вопросы

  • Нет связанных вопросов^_^