Добавление списка в фрейм данных объединяет 1 строку - PullRequest
0 голосов
/ 28 сентября 2018

ПРОБЛЕМА

Я работаю над функцией Pandas и обнаружил, что мой список ATR_l добавляется в мой фрейм данных на 1 строку позже, чем мне бы хотелось.

В частности, в столбце Выходной сигнал ATR результат 0,457500 должен быть в строке индекса 13, а не в 14 и т. Д.

Кроме того, что вычисления дают правильные результаты!

УСТРАНЕНИЕ НЕИСПРАВНОСТЕЙ

Сначала я подумал, что это может быть проблема с индексом между моим фреймом данных и списком ATR_l, однако print(i, ATR_l) показывает правильное значение ATR_l при i (13)

Я также заметил первое значение ATR_l в нулевом списке ATR_l, чего я не ожидал.Из того, что я могу сказать, это генерируется, когда я define ATR_l в ATR_l = [0] и вызывает отставание строки на выходе ATL_l.

Когда я определяю пустой список ATR_l = [], я получаю ошибку, выданную в df['ATR'] = ATR_l с ValueError: Length of values does not match length of index

Какие есть варианты удалить или не добавлять этот ноль в список в первую очередь?

К вашему сведению - с использованием Python 3.6

КОД

def ATRpd():                
    data = pd.read_csv('data.txt', sep=",", header=0)
    df = data

    n = 14
    i = 0  
    TR_l = [0]  
    ATR_l = [0]

    while i < df.index[-1]:
        TR = max(df.at[i + 1, 'High'], df.at[i, 'Close']) - min(df.at[i + 1, 'Low'], df.at[i, 'Close']) 
        TR_l.append(round(TR,3))  
        i = i + 1 
    df['TR'] = TR_l
    df['MA'] = round(df.TR.rolling(n).mean(),4)

    i = 0  
    while i < df.index[-1]:        
        if i <= n - 1:
            ATR = df.at[i, 'MA']
        elif i > n - 1:               
            ATR = (ATR * 13 + df.at[i, 'TR']) / 14        
        ATR_l.append(round(ATR,6))

        if i < 20:
      #      print(i, ATR)
            print(i, ATR_l)                
        i = i + 1

    df['ATR'] = ATR_l

    print(df.head(20))

ВЫХОД

   ASXCode   DateValue   Open    High    ...     Close     TR      MA       ATR
0      BHP  26/09/2016  21.47  21.670    ...     21.55  0.000     NaN  0.000000
1      BHP  27/09/2016  21.35  21.520    ...     21.50  0.380     NaN       NaN
2      BHP  28/09/2016  21.21  21.460    ...     21.39  0.295     NaN       NaN
3      BHP  29/09/2016  22.22  22.540    ...     22.40  1.150     NaN       NaN
4      BHP  30/09/2016  22.45  22.550    ...     22.38  0.440     NaN       NaN
5      BHP   3/10/2016  22.61  22.870    ...     22.75  0.490     NaN       NaN
6      BHP   4/10/2016  22.75  22.900    ...     22.90  0.200     NaN       NaN
7      BHP   5/10/2016  22.74  22.950    ...     22.85  0.280     NaN       NaN
8      BHP   6/10/2016  23.15  23.260    ...     23.12  0.410     NaN       NaN
9      BHP   7/10/2016  23.20  23.400    ...     23.30  0.400     NaN       NaN
10     BHP  10/10/2016  23.40  23.630    ...     23.40  0.330     NaN       NaN
11     BHP  11/10/2016  23.73  23.870    ...     23.80  0.470     NaN       NaN
12     BHP  12/10/2016  23.18  23.440    ...     23.44  0.790     NaN       NaN
13     BHP  13/10/2016  23.11  23.220    ...     22.75  0.770  0.4575       NaN
14     BHP  14/10/2016  22.34  22.590    ...     22.54  0.460  0.4904  0.457500
15     BHP  17/10/2016  22.35  22.620    ...     22.39  0.330  0.4868  0.457679
16     BHP  18/10/2016  22.30  22.660    ...     22.64  0.420  0.4957  0.448559
17     BHP  19/10/2016  22.50  22.530    ...     22.47  0.600  0.4564  0.446519
18     BHP  20/10/2016  22.58  23.025    ...     22.85  0.555  0.4646  0.457482
19     BHP  21/10/2016  22.96  23.260    ...     23.04  0.410  0.4589  0.464447

Выход ATR_l

0 [0, nan]
1 [0, nan, nan]
2 [0, nan, nan, nan]
3 [0, nan, nan, nan, nan]
4 [0, nan, nan, nan, nan, nan]
5 [0, nan, nan, nan, nan, nan, nan]
6 [0, nan, nan, nan, nan, nan, nan, nan]
7 [0, nan, nan, nan, nan, nan, nan, nan, nan]
8 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan]
9 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
10 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
11 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
12 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
13 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575]
14 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575, 0.457679]
15 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575, 0.457679, 0.448559]
16 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575, 0.457679, 0.448559, 0.446519]
17 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575, 0.457679, 0.448559, 0.446519, 0.457482]
18 [0, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 0.4575, 0.457679, 0.448559, 0.446519, 0.457482,

РЕШЕНИЕ 1

Основываясь на замечательных советах из YPadawan, приведенных ниже, я смог исправить исходную проблему с кодом, добавив +1 к df.index[-1]+1: расчета ATR.

i = 0  
    while i < df.index[-1]+1:        
        if i <= n - 1:
            ATR = df.at[i, 'MA']
        elif i > n - 1:               
            ATR = (ATR * 13 + df.at[i, 'TR']) / 14        
        ATR_l.append(round(ATR,6))

РЕШЕНИЕ 2

Принимая во внимание совет избегать итерации и необходимо использовать iterrows(), если это необходимо, я нашел следующее рабочее решение, которое мне гораздо большеЯ краткий и легкий для понимания.

Единственное, что я размышляю, - могу ли я избежать итерации ATR.

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

def ATRpd2():         
    data = pd.read_csv('data.txt', sep=",", header=0)
    df = data

    n = 14

    df['Close_prev'] = df['Close'].shift(1)
    df['TR'] = df[['High', 'Close_prev']].max(axis=1) - df[['Low', 'Close_prev']].min(axis=1)         
    df['MA'] = round(df.TR.rolling(n).mean(),6)

    ATR_l = []
    for idx, row in df.iterrows():
        if idx <= n - 1:
            ATR = row['MA']          
        else:  
            ATR = (ATR * (n - 1) + row['TR']) / n        
        ATR_l.append(round(ATR,6))      
    df['ATR'] = ATR_l

    print(df.head(20))

1 Ответ

0 голосов
/ 28 сентября 2018

Хорошо, я думаю, это поможет вам.Я думаю, что ValueError, которое вы имеете, происходит из цикла while.

'while i ValueError: Length of values does not match length of index.

Попробуйте запустить этот небольшой код, чтобы понять, почему ваш цикл while не работал так, как вы ожидали:

l = list(range(11))
print(len(l))
i = 0
l2 = []
while i < l[-1]:
    l2.append(l[i])
    i+=1
print(len(l), len(l2))

Вы должны увидеть, что len (l) больше len (l2) ...

Теперь, на самом деле, я думаю, для вас было бы предпочтительнее использовать инструменты pandas вместо обычных циклов.

Начиная с вашего фрейма данных, если вы хотите получить переменную TR,Вы должны сначала создать столбцы, соответствующие значениям «i + 1» «High» и «Low».Вы можете использовать pandas метод смещения .

df['High_plus_one'] = df['High'].shift(1)
df['Low_plus_one'] = df['Low'].shift(1)

Для создания столбца 'TR':

df['TR'] = df[['High_plus_one', 'Close', 'Low_plus_one']].max(axis=1)

Для последней части, если вы хотите создать 'ATRстолбцы, и вам действительно нужно перебирать строки вашего фрейма данных.Вы можете использовать метод df.iterrows () .

ATR_l = []
for idx, row in df.iterrows():
    if idx <= n - 1:
        ATR = row['MA']
    elif idx > n - 1:               
        ATR = (ATR * 13 + row['TR']) / 14        
    ATR_l.append(round(ATR,6))

В конце вы либо избегаете итерации по фреймам данных pandas, либо используете метод iterrows (или iteritems), если вы действительнонадо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...