从离散数据中找到相等的频率

时间:2019-03-26 13:17:24

标签: python-3.x pandas numpy discretization

我必须从时间序列数据中找到相等的宽度。

到目前为止,我可以通过手动选择每一列然后应用条件来做到这一点。但是我需要一种更快的方法。

时间序列数据:

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 个答案:

答案 0 :(得分:1)

您抱怨此算法在时间序列长度上是二次方的:

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一个具有参考性名称的函数和一个docstring,然后调用该函数。
  2. 您有一个magic numbers7 < j <= 14表达式。请给这些号码起个名字。如果名称的描述性不够,这也将使您有机会为数字添加注释行。另外,应该有一条注释,描述您要附加的三个类别的含义,也许使用诸如LOMEDHI之类的名称。
  3. (gr,group1)与(gr1,group2)的不一致,嗯,有点刺耳。

与机器通信

  1. 通常,当您关心速度时,可以将循环从python推入pandas / numpy。您已经在.sort_values()调用中完成了此操作。撰写有关数据属性的英文描述将帮助您根据documented primitives来制定算法。
  2. 您进行了排序,然后进行了N ^ 2个相等性测试,以查看排序后的值在哪里结束。您不想追踪他们的去向吗?我不知道您的算法在高层次上的作用,但是在低层次上,您似乎将每个示例归类为三个quantiles中的一个。即使不使用熊猫的显式分位数支持,您也可以添加连续的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

答案 1 :(得分:1)

如果已排序,则可以在axis=0上使用argsort来获取值在各列中的位置,然后使用不同的合并条件使用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