Как получить среднее значение увеличения значений с помощью Pandas?

Я пытаюсь выяснить среднее значение увеличения значений в моей таблице для каждого столбца.

мой стол

 A  |  B  |  C
----------------
 0  |  5  |  10
100 |  2  |  20
 50 |  2  |  30
100 |  0  |  40

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

def avergeIncreace(data,value):  #not complete but what I have so far
  x = data[value].pct_change().fillna(0).gt(0)
  print( x )  

pct_change() возвращает таблицу процента числа в этом индексе по сравнению с числом в строке перед ним. fillna(0) заменяет NaN в позиции 0 диаграммы, которую pct_change() создает с 0.gt(0) возвращает истинную или ложную таблицу в зависимости от того, является ли значение в этом индекс больше 0

текущий выход этой функции

In[1]:avergeIncreace(df,'A')
Out[1]:  0    False
         1    True
         2    False
         3    True
         Name: BAL, dtyle: bool

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

In[1]:avergeIncreace(df,'A')
Out[1]:75
In[2]:avergeIncreace(df,'B')
Out[2]:0
In[3]:avergeIncreace(df,'C')
Out[3]:10

Из моего ограниченного понимания pandas должен быть способ вернуть массив всех индексов, которые верны, а затем использовать цикл for и пройти через исходную таблицу данных, но я считаю, что у pandas должен быть способ сделать это без for петля.

что, я думаю, будет выглядеть цикл for плюс отсутствующий код, поэтому возвращаемые индексы являются истинными, а не каждым индексом

avergeIncreace(df,'A')
  indexes = data[value].pct_change().fillna(0).gt(0).index.values  #this returns an array containing all of the index (true and false)
  answer = 0
  times = 0
  for x in indexes:
    answer += (data[value][x] - data[value][x-1])
    times += 1
  print( answer/times ) 

Как добиться желаемого результата без использования цикла for в функции?


person CSstudent    schedule 24.08.2018    source источник
comment
Я понятия не имею, как вы получаете 75 для столбца «A» или 10 для столбца «B». Возможно, вы захотите проверить эти значения. Вы имеете в виду "С"? Как работает этот расчет?   -  person rahlf23    schedule 24.08.2018
comment
@ ralhlf23 10 должно было быть для столбца «C». Расчет, который я пытаюсь получить, представляет собой среднее значение увеличения значений в столбце при просмотре списка сверху вниз.   -  person CSstudent    schedule 24.08.2018
comment
например, в столбце «А» от индекса 0 (0) до индекса 1 (100) — это увеличение на 100, а индекс 2 (50) до индекса 3 (100) — это увеличение на 50, поэтому (50+100)/2 = 75. От индекса 1 к индексу 2 идет уменьшение, разница между значениями не учитывается.   -  person CSstudent    schedule 24.08.2018


Ответы (2)


Как насчет

import pandas as pd
import numpy as np

df = pd.DataFrame({'A': [0, 100, 50, 100],
                   'B': [5, 2, 2, 0],
                   'C': [10, 20, 30, 40]})

def averageIncrease(df, col_name):
    # Create array of deltas. Replace nan and negative values with zero
    a = np.maximum(df[col_name] - df[col_name].shift(), 0).replace(np.nan, 0)
    # Count non-zero values
    count = np.count_nonzero(a)

    if count == 0:
        # If only zero values… there is no increase
        return 0
    else:
        return np.sum(a) / count


print(averageIncrease(df, 'A'))
print(averageIncrease(df, 'B'))
print(averageIncrease(df, 'C'))
75.0
0
10.0
person mortysporty    schedule 24.08.2018

Вы можете использовать mask() и diff():

df.diff().mask(df.diff()<=0, np.nan).mean().fillna(0)

Урожайность:

A    75.0
B     0.0
C    10.0
dtype: float64
person rahlf23    schedule 24.08.2018
comment
Это выглядит как очень милые, чистые панды. Один вопрос - могли бы вы также сделать df.diff().mask(df.diff()<=0, np.nan).mean().fillna(0) и пропустить шаг замены? - person tobsecret; 24.08.2018
comment
Вы правы, @tobsecret, спасибо, что заметили. replace не требуется, если вы подаете np.nan к mask(), а не 0. - person rahlf23; 24.08.2018