How to create two y points for a same x?

Asked

Viewed 133 times

2

Hello, I would like to create a python routine to create "double points", where a same value of x would assume two values of y for any situation. Using the following data sequence for example:

1;5
2;2
3;4
4;10
5;6

Plotting this graph as the first column x and the second y would form a straight line.

The scenario I would like to arrive at would be the following:

1;5
1;2
2;2
2;4
3;4
3;10
4;10
4;6
5;6

And that would generate a rectangular graph. In this case, the value of x has its respective value of y, but this same value of x also has the value of y for its "x+1", and so on.

I tried to create something like a list, but without success

arquivo = open('vazmed.out', 'rt')
arq = open('vazmed2.out', 'wt')
lista = []
valor_prev = 0
for linha in arquivo:
    campo = linha.split(';')
    i = (campo[0])
    valor = float(campo[1])
    lista.append(valor)
n = len(lista)
for i in range(n-1):
    lista.append([lista[i:][:i], lista[i:][:i+1]])
    arq.write('{};{}\n' .format(i, lista[i]))
arq.close

I am new to python and this is part of my studies, so if someone can help me and explain how and why I would be grateful.

EDIT Code for transformation of positive values into 1 and negative into -1.

arquivo = open('vazdif.out', 'rt')
lista = []
valor_prev = 0
for linha in arquivo:
    campo = linha.split(',')
    cont = int(campo[0])
    vazdif = float(campo[2])
    if vazdif * valor_prev < 0:
        lista.append([lista[-1][0], - lista[-1][1]]) 
    if vazdif < 0:
        lista.append([cont, -1])                                         
    else:
        lista.append([cont, 1])
    valor_prev = vazdif                                                 
fou = open('res_id.out','wt')
for i in lista:
    fou.write('%4d,%8.4f\n' % (i[0],i[1]))
fou.close()

The output file of this code is as follows::

   0, -1.0000
   1, -1.0000
   2, -1.0000
   3, -1.0000
   4, -1.0000
   5, -1.0000
   5,  1.0000
   6,  1.0000
   7,  1.0000
   8,  1.0000
   9,  1.0000
  10,  1.0000
  11,  1.0000
  12,  1.0000
  13,  1.0000
  14,  1.0000
  14, -1.0000
  15, -1.0000
  16, -1.0000
  17, -1.0000
  18, -1.0000
  19, -1.0000
  20, -1.0000

As you can see, whenever the value changes from negative to positive, the i repeats with the value of i previous. However the i is not part of the data effectively, being only an index.

Important to note that it is only the index that will repeat, not the value itself.

2 answers

0


Leafar’s answer is correct, but it will only work if you treat the data correctly.

Treating data from a line-separated file

texto = '''1;5
2;-2
3;4.5
4;10
5;6'''
# Para cada linha que tiver na string, gerar uma lista de valores separado por ;
lista = [i.split(';') for i in texto.splitlines()]
print(lista)
# [['1', '5'], ['2', '-2'], ['3', '4.5'], ['4', '10'], ['5', '6']]

Now just apply the logic offered by Leafar and treat the strings:

m = []
for i in range(len(lista)):
    # Primeiro valor registra como INT e segundo valor registra como FLOAT
    m.append([int(lista[i][0]), float(lista[i][1])])

    if i < len(lista)-1:
        m.append([int(lista[i][0]), float(lista[i+1][1])])
 print(m)
 # [[1, 5.0], [1, -2.0], [2, -2.0], [2, 4.5], [3, 4.5], [3, 10.0], [4, 10.0], [4, 6.0], [5, 6.0]]

And to pull the dice:

for i in m:
    print(f'index = {i[0]}; valor = {i[1]}')

0

Well, the main problem is that you are using the list index to 'save' the value x, but this is not possible when you have two elements with the same value x, since the list soh can have a value y saved in that Dice x.

The other problem is that you’re adding all the original points in the list before you start adding the new ones, which prevents you from sorting the points the way you put them in the example.

The command lista[i:][:i] Also it’s pretty strange. What you’re doing here is cutting all the first ones i-1 list elements and, given the list resulting from this cut, keep only the first i elements. In any case, this operation will result in a list, which does not seem to be what you want there. I recommend until you do some experiments giving print on different values of i as Indice to better understand how lists work.

Try to do something about it:

l = [[1,5], [2,2], [3,4], [4,10], [5,6]] # Troque pela leitura do arquivo...

m = []
for i in range(len(l)):
    m.append(l[i])

    if i < len(l)-1:
        m.append([l[i][0], l[i+1][1]])

# Escreva os elementos de m no arquivo...

This code results in m = [[1, 5], [1, 2], [2, 2], [2, 4], [3, 4], [3, 10], [4, 10], [4, 6], [5, 6]], which seems to be the result you expect.

  • It worked in parts, I think maybe I didn’t explain it right, but the first column, which goes from 1 to 5, is not part of the list, so what I’m actually working on is [5, 2, 4, 10, 6]. But when I try to iterate more or less the same way as you presented, the following error appears, 'int' object has no attribute '__getitem__'. And another thing that may be making a mistake is the fact that the list that I own doesn’t just contain integers, it has floats and negative numbers as well, something like that l = [5 ,-2 ,4 ,10.4 ,6]

  • Hmm, right. Can you give an exact example of what behavior you’re trying to implement (for example, which exact output you wait for an input)? And which command generates this error?

  • The input for this would be a file (txt for example) where I would have determined number of columns. One of these columns would be the i, that nothing else is an index (time for example) of the value of the second column (which I effectively want to work on), so given the entry of the list I used as an example, the output would be i( that would have two equal values) and m for example, that would be the values themselves. The case is that a same i (x-axis) will have two values, its own and the value of i relative to `````i+1`````. And then if you plot it the graph is "square".

  • The mistake I mentioned is related to m.append([l[i][0], l[i+1][1]])

  • I’m going to do an Edit in the post and put in another code that might help. This code does almost the same thing. but the difference is that in this I had a list of positive and negative numbers, and when the number was negative it assumes the value -1 in the output, when positive it assumes the value 1. However, whenever the signal exchange occurs, a point is created in the same x, but with the value of 1 reversed. So if I’m in a negative sequence, and then the next one is positive, the last negative x of the sequence will have two values of y, one negative and one positive.

  • There’s about the same idea of what I tried to do, and the way you tried to help me. however it was a very specific case, -1 and 1, negative and positive. Now I will be able to have floats, negative, positive and etc

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.