Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建具有相同自相关的排列_Python_Numpy_Random_Permutation - Fatal编程技术网

Python 创建具有相同自相关的排列

Python 创建具有相同自相关的排列,python,numpy,random,permutation,Python,Numpy,Random,Permutation,我的问题类似于,但不同的是我需要一个0和1的数组作为输出。我有一个原始的时间序列,由零和具有高自相关性的一组成(即,这些时间序列是聚集的)。对于一些显著性测试,我需要创建具有相同数量的0和1的随机数组。例如,原始数组的排列,但是,自相关也应保持与原始数组相同/相似,因此简单的排列对我没有帮助 因为我正在做多个实现,所以我需要一个尽可能快的解决方案。非常感谢您的帮助 根据您提到的问题,您希望排列x,以便 np.corrcoef(x[0: len(x) - 1], x[1: ])[0][1] 不会

我的问题类似于,但不同的是我需要一个0和1的数组作为输出。我有一个原始的时间序列,由零和具有高自相关性的一组成(即,这些时间序列是聚集的)。对于一些显著性测试,我需要创建具有相同数量的0和1的随机数组。例如,原始数组的排列,但是,自相关也应保持与原始数组相同/相似,因此简单的排列对我没有帮助


因为我正在做多个实现,所以我需要一个尽可能快的解决方案。非常感谢您的帮助

根据您提到的问题,您希望排列
x
,以便

np.corrcoef(x[0: len(x) - 1], x[1: ])[0][1]
不会改变

假设序列x由

Z1O1Z2O2Z3O3。。。好的

其中,每个zi是0的序列,每个oi是1的序列。(有四种情况,取决于序列是从0开始还是从1开始,以及它是以0结束还是以1结束,但原则上它们都是相同的)

假设p和q分别为{1,…,k}的排列,并考虑序列

zp[1]oq[1]zp[2]oq[2]zp[3]oq[3]。。。zp[k]oq[k]

也就是说,0s和1s的每个游程长度子序列都在内部进行了排列

例如,假设原始序列是

0,0,0,1,1,0,1

然后

0,0,0,1,0,1,1,

是这样一种排列,以及

0,1,1,0,0,0,1,

0,1,0,0,0,1,1

执行此排列不会改变相关性:

  • 在每次运行中,差异是相同的
  • 管路之间的边界与以前相同
因此,这提供了一种生成不影响相关性的排列的方法。(另外,最后请参阅另一种更简单、更有效的方法,它可以在许多常见情况下工作。)

我们从函数
preprocess
开始,它获取序列,并返回一个元组
以0、0、1开头,分别表示

  • x
    是否以0开头
  • 0运行
  • 1运行
在代码中,这是

import numpy as np
import itertools

def preprocess(x):
    def find_runs(x, val):
        matches = np.concatenate(([0], np.equal(x, val).view(np.int8), [0]))
        absdiff = np.abs(np.diff(matches))
        ranges = np.where(absdiff == 1)[0].reshape(-1, 2)
        return ranges[:, 1] - ranges[:, 0]

    starts_with_zero = x[0] == 0

    run_lengths_0 = find_runs(x, 0)
    run_lengths_1 = find_runs(x, 1)
    zeros = [np.zeros(l) for l in run_lengths_0]
    ones = [np.ones(l) for l in run_lengths_1]

    return starts_with_zero, zeros, ones
(此函数借用了对的回答。)

要使用此功能,您可以执行以下操作,例如:

x = (np.random.uniform(size=10000) > 0.2).astype(int)

starts_with_zero, zeros, ones = preprocess(x)
现在我们编写一个函数在内部排列0和1运行,并连接结果:

def get_next_permutation(starts_with_zero, zeros, ones):
    np.random.shuffle(zeros)
    np.random.shuffle(ones)

    if starts_with_zero:
        all_ = itertools.izip_longest(zeros, ones, fillvalue=np.array([]))
    else:
        all_ = itertools.izip_longest(ones, zeros, fillvalue=np.array([]))
    all_ = [e for p in all_ for e in p]

    x_tag = np.concatenate(all_)

    return x_tag
要生成另一个置换(具有相同的相关性),可以使用

x_tag = get_next_permutation(starts_with_zero, zeros, ones)
要生成许多排列,可以执行以下操作:

starts_with_zero, zeros, ones = preprocess(x)

for i in range(<number of permutations needed):
    x_tag = get_next_permutation(starts_with_zero, zeros, ones)
然后我们得到:

0.00674330566615
[ 1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  0.
  1.  1.  0.  1.  1.  1.  1.  0.  1.  1.  0.  0.  1.  0.  1.  1.  1.  1.
  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
0.00674330566615
[ 1.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  1.  1.  1.  1.  0.  0.  1.  0.
  1.  1.  1.  1.  0.  0.  0.  1.  1.  1.  1.  1.  1.  1.]
0.00674330566615
[ 1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  0.  0.  0.  0.  1.  0.  1.  1.
  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.
  1.  1.  1.  1.  1.  1.  0.  1.  0.  0.  1.  1.  1.  0.]
0.00674330566615
[ 1.  1.  1.  1.  0.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.
  1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.
  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  0.  1.]
0.00674330566615
[ 1.  1.  1.  1.  0.  0.  0.  0.  1.  1.  0.  1.  1.  0.  0.  1.  0.  1.
  1.  1.  0.  1.  0.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  0.  1.
  0.  1.  1.  1.  1.  1.  1.  0.  1.  0.  1.  1.  1.  1.]
0.00674330566615
[ 1.  1.  0.  1.  1.  1.  0.  0.  1.  1.  0.  1.  1.  0.  0.  1.  1.  0.
  1.  1.  1.  0.  1.  1.  1.  1.  0.  0.  0.  1.  1.  1.  1.  1.  1.  1.
  0.  1.  1.  1.  1.  0.  1.  1.  0.  1.  0.  0.  1.  1.]
0.00674330566615
[ 1.  1.  0.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.  1.  1.
  1.  1.  0.  1.  0.  1.  1.  0.  1.  0.  1.  1.  1.  1.]
0.00674330566615
[ 1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  0.  1.  0.  1.  1.
  1.  1.  1.  0.  1.  0.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.  1.  0.
  0.  1.  1.  1.  0.  1.  1.  0.  1.  1.  0.  1.  1.  1.]
0.00674330566615
[ 1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.
  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.
  0.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  1.]
0.00674330566615
[ 1.  1.  0.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  0.  1.  0.  1.
  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  1.
  1.  1.  0.  1.  0.  1.  0.  1.  1.  1.  1.  1.  1.  0.]

注意,如果

  • 你的序列长度是n


  • 我现在想不出一个很快的解决方案。直截了当的方法似乎是确定每个clustersize的出现次数,然后用这些簇填充一个新数组,但位置是随机的。这将需要N次迭代,其中N是最大集群大小……这是一个很好的答案,但值得指出的是,“排列序列”并不能给出所有可能的解决方案。例如,对于
    [0,1,1,1,0,1,0]
    ,您将无法获得
    [0,1,1,0,1,1,0]
    @UlrichStern这是一个很好的观点-谢谢!我试图在生成大量置换和快速生成时间之间找到一个很好的折衷点。不过,这是一个非常好的观点,我将把它添加到答案中(如果你同意的话)。
    0.00674330566615
    [ 1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  0.
      1.  1.  0.  1.  1.  1.  1.  0.  1.  1.  0.  0.  1.  0.  1.  1.  1.  1.
      0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
    0.00674330566615
    [ 1.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
      1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  1.  1.  1.  1.  0.  0.  1.  0.
      1.  1.  1.  1.  0.  0.  0.  1.  1.  1.  1.  1.  1.  1.]
    0.00674330566615
    [ 1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  0.  0.  0.  0.  1.  0.  1.  1.
      1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.
      1.  1.  1.  1.  1.  1.  0.  1.  0.  0.  1.  1.  1.  0.]
    0.00674330566615
    [ 1.  1.  1.  1.  0.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.
      1.  1.  1.  1.  1.  0.  0.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.
      1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  0.  1.]
    0.00674330566615
    [ 1.  1.  1.  1.  0.  0.  0.  0.  1.  1.  0.  1.  1.  0.  0.  1.  0.  1.
      1.  1.  0.  1.  0.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  0.  0.  1.
      0.  1.  1.  1.  1.  1.  1.  0.  1.  0.  1.  1.  1.  1.]
    0.00674330566615
    [ 1.  1.  0.  1.  1.  1.  0.  0.  1.  1.  0.  1.  1.  0.  0.  1.  1.  0.
      1.  1.  1.  0.  1.  1.  1.  1.  0.  0.  0.  1.  1.  1.  1.  1.  1.  1.
      0.  1.  1.  1.  1.  0.  1.  1.  0.  1.  0.  0.  1.  1.]
    0.00674330566615
    [ 1.  1.  0.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
      1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.  1.  1.
      1.  1.  0.  1.  0.  1.  1.  0.  1.  0.  1.  1.  1.  1.]
    0.00674330566615
    [ 1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  0.  1.  0.  1.  1.
      1.  1.  1.  0.  1.  0.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.  1.  0.
      0.  1.  1.  1.  0.  1.  1.  0.  1.  1.  0.  1.  1.  1.]
    0.00674330566615
    [ 1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.
      1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  0.  1.  1.  1.
      0.  1.  1.  1.  1.  1.  1.  0.  1.  1.  0.  1.  1.  1.]
    0.00674330566615
    [ 1.  1.  0.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  0.  1.  0.  1.
      1.  1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  1.
      1.  1.  0.  1.  0.  1.  0.  1.  1.  1.  1.  1.  1.  0.]