Numpy: разделить текущий ряд на предыдущий - PullRequest
0 голосов
/ 19 февраля 2019

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

0.086206438,10
0.086425551,12
0.089227066,20
0.089262508,24
0.089744425,30
0.090036815,40
0.090054172,28
0.090377569,28
0.090514071,28
0.090762872,28
0.090912691,27

Для воспроизводимости, я имеюподелился данными трех временных рядов, которые я использую здесь .

Из столбца 2 я хотел прочитать текущую строку и сравнить ее со значением предыдущей строки.Если оно больше, я продолжаю сравнивать.Если текущее значение меньше значения предыдущего ряда, я хочу разделить текущее значение (меньше) на предыдущее значение (больше).Позвольте мне прояснить это.Например, в приведенном выше примере записи, которую я предоставил, седьмая строка (28) меньше значения в шестой строке (40), поэтому она будет (28/40 = 0,7).

Вот мойПример кода.

import numpy as np
import pandas as pd
import csv
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import norm
from statsmodels.graphics.tsaplots import plot_acf, acf


protocols = {}


types = {"data1": "data1.csv", "data2": "data2.csv", "data3": "data3.csv"}

for protname, fname in types.items():
    col_time = []  
    col_window = [] 
    with open(fname, mode='r', encoding='utf-8-sig') as f:
        reader = csv.reader(f, delimiter=",")
        for i in reader:
            col_time.append(float(i[0]))
            col_window.append(int(i[1]))
    col_time, col_window = np.array(col_time), np.array(col_window)
    diff_time = np.diff(col_time)
    diff_window = np.diff(col_window)
    diff_time = diff_time[diff_window > 0] 
    diff_window = diff_window[diff_window > 0] # To keep only the increased values
    protocols[protname] = {
        "col_time": col_time,
        "col_window": col_window,
        "diff_time": diff_time,
        "diff_window": diff_window,
    }


# Plot the quotient values
rt = np.exp(np.diff(np.log(col_window)))

for protname, fname in types.items():
    col_time, col_window = protocols[protname]["col_time"], protocols[protname]["col_window"]
    rt = np.exp(np.diff(np.log(col_window)))
    plt.plot(np.diff(col_time), rt, ".", markersize=4, label=protname, alpha=0.1)
    plt.ylim(0, 1.0001)
    plt.xlim(0, 0.003)
    plt.title(protname)
    plt.xlabel("time")
    plt.ylabel("difference")
    plt.legend()
    plt.show()

Это дает мне следующие графики

enter image description here

enter image description here enter image description here

Однако, когда я делаю это

rt = np.exp(np.diff(np.log(col_window)))

Он делит каждую текущую строку на предыдущую строку, что не является тем, что я хочу.Как я объяснил выше на примере моего вопроса, я хочу разделить текущее значение строки столбца 2 на предыдущее значение ТОЛЬКО столбца 2, если текущее значение строки меньше предыдущего значения.Наконец, нанесите частное по разнице временных отметок (col_time в моем коде выше).Как я могу это исправить?

1 Ответ

0 голосов
/ 19 февраля 2019

Если вам не нужен модуль csv, я бы порекомендовал использовать метод numpy loadtxt для загрузки ваших файлов, то есть

col_time,col_window = np.loadtxt(fname,delimiter=',').T

Эта единственная строказаботится о первых 8 строках вашего цикла for.Обратите внимание, что операция транспонирования (.T) необходима для преобразования исходной формы данных (N строки по 2 столбцам) в 2 строку по N форме столбца, которая распаковывается в col_time и col_window.Также обратите внимание, что loadtxt автоматически загружает данные в numpy.array объекты.

Что касается вашего фактического вопроса, я бы использовал нарезку и маскировку:

trailing_window = col_window[:-1] # "past" values at a given index
leading_window  = col_window[1:]  # "current values at a given index
decreasing_mask = leading_window < trailing_window
quotient = leading_window[decreasing_mask] / trailing_window[decreasing_mask]
quotient_times = col_time[decreasing_mask]

Тогда quotient_times может бытьпостроен против quotient.

В качестве альтернативы можно использовать метод numpy where, чтобы получить индексы с маской True:

trailing_window = col_window[:-1] # "past" values at a given index
leading_window  = col_window[1:]  # "current values at a given index
decreasing_inds = np.where(leading_window < trailing_window)[0]
quotient = leading_window[decreasing_inds] / trailing_window[decreasing_inds]
quotient_times = col_time[decreasing_inds]

Имейте в видучто весь приведенный выше код все еще выполняется в первом цикле for, но теперь rt вычисляется внутри цикла как quotient.Таким образом, после вычисления quotient_times для построения (также внутри первого цикла):

# Next line opens a new figure window and then clears it
figure(); clf()
# Updated plotting call with the syntax from the answer
plt.plot(quotient_times,quotient,'.',ms=4,label=protname,alpha=0.1)
plt.ylim(0, 1.0001)
plt.xlim(0, 0.003)
plt.title(protname)
plt.xlabel("time")
plt.ylabel("quotient")
plt.legend()
# You may not need this `plt.show()` line 
plt.show()
# To save the figure, one option would be the following:
# plt.savefig(protname+'.png')    

Обратите внимание, что вам может потребоваться вывести строку plt.show() из цикла.

Помещениеэто вместе для вас,

import numpy as np
import matplotlib.pyplot as plt

protocols = {}

types = {"data1": "data1.csv", "data2": "data2.csv", "data3": "data3.csv"}

for protname, fname in types.items():
    col_time,col_window = np.loadtxt(fname,delimiter=',').T
    trailing_window = col_window[:-1] # "past" values at a given index
    leading_window  = col_window[1:]  # "current values at a given index
    decreasing_inds = np.where(leading_window < trailing_window)[0]
    quotient = leading_window[decreasing_inds] / 
    trailing_window[decreasing_inds]
    quotient_times = col_time[decreasing_inds]
    # Still save the values in case computation needs to happen later 
    # in the script    
    protocols[protname] = {
        "col_time": col_time,
        "col_window": col_window,
        "quotient_times": quotient_times,
        "quotient": quotient,
    }
    # Next line opens a new figure window and then clears it
    plt.figure(); plt.clf()
    plt.plot(quotient_times,quotient, ".", markersize=4, label=protname, alpha=0.1)
    plt.ylim(0, 1.0001)
    plt.xlim(0, 0.003)
    plt.title(protname)
    plt.xlabel("time")
    plt.ylabel("quotient")
    plt.legend()
    # To save the figure, one option would be the following:
    # plt.savefig(protname+'.png')
# This may still be unnecessary, especially if called as a script
# (just save the plots to `png`).
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...