Warning looping Python Pandas, How do looping differently?

1

Personally I'm doing this looping here:

for i in range(1, len(candles)):
    if candles['askclose'][i]> candles['askopen'][i]:
        candles['Fechamento'][i]= 'alta'

But the jupyternotebook always returns this warning and sometimes hangs and does not advance, any idea how to improve or make this looping different, to avoid the warning:

Warning:

C:\Users\Jair\Anaconda3\lib\site-packages\ipykernel_launcher.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  This is separate from the ipykernel package so we can avoid doing imports until

The mask as the friend suggested is great solution, but when I have a larger loop like this:

for i in range(1, len(candles)):
    tamanho_twin = 0
    if candles['Fechamento'][i]=='baixa' and candles['Fechamento'][i-1] == 'alta':
        if candles['askclose'][i] <= candles['askopen'][i-1] and candles['MA20'][i]<candles['MA20'][i-2]:
            limite_sombraV= ((candles['askclose'][i]-candles['askopen'][i])*0.1)+candles['askclose'][i]
            if candles['asklow'][i] == limite_sombraV:
                tamanho_twin = candles['askclose'][i]+candles['askopen'][i]
                candles['Twintower'][i] = 0
                candles['Tamanho_Twin'][i] = candles['askclose'][i]+candles['askopen'][i]
    
asked by anonymous 07.12.2018 / 00:30

1 answer

0

If I understand the question you just need a mask, see:

import pandas as pd

a = [[1,2,'n/a'],[2,1,'n/a'],[3,4,'n/a'],[4,3,'n/a']]
candles = pd.DataFrame(a,columns=['askclose', 'askopen', 'fechamento'])

print('Candles original', candles, sep='\n')
Candle original
   askclose  askopen fechamento
0         1        2        n/a
1         2        1        n/a
2         3        4        n/a
3         4        3        n/a

# Criação da mascara
mask = candles.askopen>candles.askclose

# Atualização do candles
candles.loc[mask, 'fechamento'] = 'alta'

print('Candles atualizado', candles, sep='\n')
Candles atualizado
   askclose  askopen fechamento
0         1        2       alta
1         2        1        n/a
2         3        4       alta
3         4        3        n/a

Note:
To assign a different value when askopen is smaller, create a second mask or deny the mask created with a bitwise operator ( candles.loc[~mask, 'fechamento'] = 'baixa' )

See working at repl.it.

  

Edited
  After editing it to the question I understood that it is necessary to iterate the dataframe, I created a function that iterates df received and changes it based on the previous value of a column, to simplify I used numerical values and column names based on the first 3 letters (a, b, c). Just adapt to your need.

import pandas as pd
import numpy as np

def iter_df(df):
    for i in range(0, len(df)):
        if i !=0: 
            print('indice atual: ',i, 'coluna: a')
            print('valor atual :', df.iloc[i]['a'], 'valor anterior: ', 
                   df.iloc[i-1]['a'])
            print('-'*36)

        # Alterando o valor de uma coluna baseado no valor do indice anterior
        if df.iloc[i-1]['a']==11:
            df.iloc[i]['a']=99
    return df 

a = np.array([[1, 2, 3], [11, 12, 13], [21, 22, 23], [31, 32, 33], [41, 42, 43]])
df = pd.DataFrame(a, columns=['a', 'b', 'c'])

print ('df antes da atualizacao', df, sep='\n')
df antes da atualizacao
    a   b   c
0   1   2   3
1  11  12  13
2  21  22  23
3  31  32  33
4  41  42  43

print ('df pós atualizacao', iter_df(df),sep='\n' )
indice atual:  1 coluna: a
valor atual : 11 valor anterior:  1
------------------------------------
indice atual:  2 coluna: a
valor atual : 21 valor anterior:  11
------------------------------------
indice atual:  3 coluna: a
valor atual : 31 valor anterior:  21
------------------------------------
indice atual:  4 coluna: a
valor atual : 41 valor anterior:  31
------------------------------------
df pós atualizacao
    a   b   c
0   1   2   3
1  11  12  13
2  99  22  23
3  31  32  33
4  41  42  43

See this new version on repl.it.

    
07.12.2018 / 04:03