Как конвертировать кортежи в поплавки? - PullRequest
0 голосов
/ 27 мая 2019

Я задал похожий вопрос вчера, но удалил его, потому что теперь я понимаю, что он не был правильно сформулирован (я новичок в Python).Поэтому мне было трудно помочь.Мои извенения;Я знаю, что это не очень хорошая форма.Я надеюсь, что я сделал лучшую работу здесь.

Справочная информация: у меня есть несколько выходных файлов из моделирования.Я хочу импортировать и выводить данные из файлов.Большинство файлов имеют номера, расположенные в столбцах.Легко использовать «loadtxt» для импорта чисел.Они прибывают как массивы поплавков (насколько я знаю), и тогда я могу построить их.

Проблема: я боролся с одним из файлов в течение трех дней, потому что он не расположен в хороших столбцах.Он состоит из текста и чисел, и мне нужно сначала извлечь нужные мне числа перед построением графика (нажмите на предыдущее слово «один», чтобы увидеть короткий фрагмент файла - реальный - тысячи строк).Я назову это «трудным» файлом.Я могу извлекать и импортировать числа, но они поступают в виде кортежей, и я не смог превратить их в массив чисел с плавающей запятой, чтобы их можно было сопоставить с данными, которые я импортировал из других файлов.

Я не очень понимаю, что такое кортежи, даже после попытки в течение последних нескольких дней, так что, вероятно, я где-то допустил глупую ошибку.В моем примере ниже я попытался использовать метод для преобразования кортежей в массивы с плавающей точкой.Любой совет будет очень признателен.Пожалуйста, не стесняйтесь высказывать любую критику по поводу того, как я могу сделать это более ясным.

Мой код:

from scipy import *
import numpy as np
import matplotlib
matplotlib.use(matplotlib.get_backend())
import matplotlib.pyplot as plt
import re

while True:
    try:
        cellfile1="pathToDifficultFile" #I have to use "regex" to extract numbers from a file that contains numbers and text. They arrive as some kind of tuple.
        infile1=open(cellfile1,'r')
        cellfile2="pathToEasyFile" #I can use "loadtxt" to get the data. The data arrive as nice arrays of floats--for example, times: 1, 2, 3, 4,... seconds.
        infile2=open(cellfile2,'r')
        break
    except IOError as e:
        print("Cannot find file..try again.")

skip        = int(input('How many steps to skip?')) # Skip the first few time steps (first rows in my output files) because the result often not correct in my simulations.
cell        = loadtxt(cellfile2,skiprows=2+skip)
step        = np.array(cell[:,0]) # This is what I want to be the x axis data in my plot; it's just time, like 1, 2, 3, 4 seconds.

# Extract numbers I need from the difficult file
for line in infile1: #   Iterate over the lines
    match = re.search('Total=     (\d.+)', line) # Returns weird tuple.
    if match: # Did we find a match?
        totalMoment0 = match.group(1) # Yes, process it

totalMoment = np.asarray(totalMoment0) #Here I'm trying to convert the weird imported tuple data from regex directly above to an array of floats so I can plot it versus the time data imported from the other file.
avgtotalMoment =np.cumsum(totalMoment)/(step-skip)
plt.plot(step,totalMoment,'-')
plt.plot(step,avgtotalMoment,'-')
plt.xlabel('Timestep')
plt.ylabel('Imported difficult data')
plt.show()

Вывод из моего кода:

How many steps to skip?0
[[  1.00000000e+00   5.00000000e-01   7.82390980e-01 ...,  -9.94476371e+02
   -9.93104616e+02   2.86557169e+01]
 [  2.00000000e+00   1.00000000e+00   7.70928719e-01 ...,  -9.94464419e+02
   -9.93104149e+02   5.06833816e+00]
 [  3.00000000e+00   1.50000000e+00   7.50579191e-01 ...,  -9.94443439e+02
   -9.93103532e+02   5.15203691e+00]
 ..., 
 [  2.13340000e+04   1.06670000e+04   7.57428741e-01 ...,  -9.94623426e+02
   -9.93037136e+02   1.91433048e+01]
 [  2.13350000e+04   1.06675000e+04   7.28059027e-01 ...,  -9.94593384e+02
   -9.93036461e+02   3.76293707e+00]
 [  2.13360000e+04   1.06680000e+04   7.08130301e-01 ...,  -9.94572844e+02
   -9.93035855e+02   4.03132892e+00]]
Traceback (most recent call last):
  File "momentsFromQsMomentsFile.py", line 42, in <module>
    plt.plot(step,totalMoment,'-')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/pyplot.py", line 2987, in plot
    ret = ax.plot(*args, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 4137, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 317, in _grab_next_args
    for seg in self._plot_args(remaining, kwargs):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 295, in _plot_args
    x, y = self._xy_from_xy(x, y)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 237, in _xy_from_xy
    raise ValueError("x and y must have same first dimension")
ValueError: x and y must have same first dimension

Ответы [ 2 ]

0 голосов
/ 27 мая 2019

Вот как получить доступ к значению кортежа и преобразовать строку в число с плавающей точкой:

>>> m = re.search(r'Total=\s+([0-9\-\.]+)', " Random Stuff 12348    Total=     -23.94409825335")
>>> m.groups()
('-23.94409825335',)
>>> result = float(m.groups()[0])
>>> result
-23.94409825335
0 голосов
/ 27 мая 2019

Я думаю, что проблема здесь может быть в вашем цикле for.

for line in infile1: #   Iterate over the lines
    match = re.search('Total=     (\d.+)', line) # Returns a match object
    if match: # Did we find a match?
        totalMoment0 = match.group(1) # this will be a string, assuming the group has a match.

Заметили, как вы назначаете totalMoment0 каждый раз, когда находите совпадение?Таким образом, вы получаете строку каждый раз, а затем перезаписываете ее.Другая проблема с этим, я думаю, состоит в том, что строки в python являются итеративными!Итак, ваше последнее совпадение, скажем, "1000" - это строка, которую asarray numpy преобразует в массив, к счастью, как array('1','0', '0', '0')!

Что вам нужно сделать, это добавить значения следующим образом:

output_matches = [] # set up an empty list
for line in infile1: #   Iterate over the lines
    match = re.search('Total=     (\d.+)', line) # Try and get a match
    if match: # Did we find a match?
        output_matches.append(float(match.group(1))) # append the match to the list, casting the match as a float as you do so. 

Обратите внимание, что если ваше регулярное выражение здесь плохо, вы можете получить ошибку, пытаясь привести его к float.Но я оставлю эту проблему будущему тебе!

...