Нахождение равной частоты по дискретным данным - PullRequest
1 голос
/ 26 марта 2019

мне нужно найти равную ширину по данным временного ряда.

Пока что я мог бы сделать это, вручную выбрав каждый столбец и применив условие.Но мне нужен более быстрый способ сделать это.

Данные временных рядов:

Time    ulaR    trxA

0       0.6457325   0.4040438
50      0.4594477   0.4172161
100     0.4244469   0.3878299
150     0.391452    0.49735
200     0.3570379   0.4930038
250     0.3730624   0.4221448
300     0.3676819   0.3796647
350     0.3688949   0.4228213
400     0.4018654   0.439482
450     0.3934677   0.4039933
500     0.3571651   0.3264575
550     0.5451287   0.3471816
600     0.6520524   0.3710635
650     0.6776012   0.4173777
700     0.684412    0.3812378
750     0.7298819   0.3735065
800     0.739083    0.3195176
850     0.6394782   0.213515
900     0.6483277   0.3721211
950     0.7003584   0.3528451
1000    0.6926971   0.3867717

Мой код:

import numpy as np
import pandas as pd
import csv
import array as ar

infile="Ecoli-1_dream4_timeseries.tsv"
outfile="tempecoli.csv"
df=pd.read_csv(infile,delimiter="\t",dtype=float)

a1=np.array(df['ulaR'])
s=df.sort_values(['ulaR'])
s1=np.array(s['ulaR'])
gr=list()

for i in range(len(s1)):
  for j in range(len(a1)):
    if s1[i]==a1[j]:
        if j<=7:
            gr.append(0)
        elif j>7 and j<=14:
            gr.append(1)
        else:
            gr.append(2)


##########

a1=np.array(df['trxA'])
s=df.sort_values(['trxA'])
s1=np.array(s['trxA'])
gr1=list()

for i in range(len(s1)):
  for j in range(len(a1)):
     if s1[i]==a1[j]:
         if j<=7:
            gr1.append(0)
         elif j>7 and j<=14:
            gr1.append(1)
         else:
            gr1.append(2)

#############


group1=pd.Series(gr,name="ulaR")
group2=pd.Series(gr1,name="trxA")
df2=pd.concat([group1,group2],axis=1)
df2.to_csv("ecoli1.csv")
print("Completed")

Если вы запустите этот код, выполучит результат.Я не хочу никакого нового результата, все, что я хочу, это более эффективный по времени код, чтобы получить желаемый результат.Потому что написание имен каждого кода, а затем применение условий занимает много времени.Небольшая помощь будет оценена.Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Вы можете использовать argsort на axis=0, чтобы получить позицию значения в каждом столбце, если отсортировано, тогда digitize с различными условиями биннинга, чтобы получить три значения 0, 1 или 2, как в вашем случае:

l_col = ['ulaR', 'trxA']
bins = [-1., 7., 14., np.inf] # I use -1 as first bound to ensure 0 is in the same bin than 1 to 7
df2 = pd.DataFrame(np.digitize(df[l_col].values.argsort(axis=0), bins, right=True)-1,
                       columns=l_col)
# the -1 after digitize is because it starts at 1 not 0
1 голос
/ 26 марта 2019

Вы жалуетесь, что этот алгоритм является квадратичным по длительности временных рядов:

for i in range(len(s1)):
  for j in range(len(a1)):
    if s1[i]==a1[j]:
        if j<=7:
            gr.append(0)
        elif j>7 and j<=14:
            gr.append(1)
        else:
            gr.append(2)

общение с людьми

С точки зрения документации у вашей реализации есть несколько проблем.

  1. Прежде всего, вы не назвали интересующий алгоритм. Пожалуйста, def функция, с информативным именем и строка документа , и вызовите функцию.
  2. У вас есть выражение с магическими числами , 7 < j <= 14. Пожалуйста, дайте имена этим номерам. Это также даст вам возможность добавить строку комментария для номера, если имя недостаточно наглядно. Кроме того, должен быть комментарий, описывающий значение трех категорий, которые вы добавляете, возможно, с использованием имен, таких как LO, MED, HI.
  3. Несоответствие (gr, group1) и (gr1, group2), конечно, немного неприятно.

общение с машиной

  1. Как правило, когда вам небезразлична скорость, путь в пету из питона в панды / numpy - это путь. Вы уже сделали это в вызове .sort_values(). Написание англоязычных описаний ваших свойств данных поможет вам сформулировать свой алгоритм в виде документированных примитивов .
  2. Вы отсортировали, а затем извращенно выполняете N ^ 2 тестов на равенство, чтобы увидеть, где находятся отсортированные значения. Разве вы не хотели бы отслеживать, куда они пошли? Я не знаю, что делает ваш алгоритм на высоком уровне, но на низком уровне похоже, что вы классифицируете каждый пример на один из трех квантилей . Даже без использования явной поддержки квантилей pandas вы могли бы привязать последовательный столбец index (или массировать существующий столбец Time, см. Ниже), чтобы порядковый номер индекса сопровождал значение ваших данных во время сортировки. Тогда ваше линейное сканирование может легко увидеть, было ли текущее значение данных около начала или конца ряда. Итог: дайте машине то, что ей скоро понадобится, не раздевайте ординалы только для того, чтобы восстановить их позже.

отсортированные данные

$ sort -nk2 < ecoli.tsv
200     0.3570379   0.4930038
500     0.3571651   0.3264575
300     0.3676819   0.3796647
350     0.3688949   0.4228213
250     0.3730624   0.4221448
150     0.391452    0.49735
450     0.3934677   0.4039933
400     0.4018654   0.439482
100     0.4244469   0.3878299
50      0.4594477   0.4172161
550     0.5451287   0.3471816
850     0.6394782   0.213515
0       0.6457325   0.4040438
900     0.6483277   0.3721211
600     0.6520524   0.3710635
650     0.6776012   0.4173777
700     0.684412    0.3812378
1000    0.6926971   0.3867717
950     0.7003584   0.3528451
750     0.7298819   0.3735065
800     0.739083    0.3195176
...