Python numpy:在numpy 2-D数组中对每对列执行函数?

时间:2018-04-13 16:25:34

标签: python function numpy

我正在尝试将函数应用于numpy数组中的每对列(每列都是个体的基因型)。

例如:

@Bean
public IntegrationFlow jmsInboundFlow(DefaultMessageListenerContainer myJmsListenerContainerFactory,
        SessionFactory<FTPFile> sessionFactory) {
    return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(myJmsListenerContainerFactory))
            .handle(generateFilesToFtp())
            .split(splitEachFileToSeperateMessage)
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .handle(Ftp.outboundAdapter(sessionFactory)
                    .remoteDirectory("/")
                    .useTemporaryFileName(false),
                    c -> c.advice(expressionAdvice(c))
            )
            .get();
}

@Bean
public Advice expressionAdvice(GenericEndpointSpec<FileTransferringMessageHandler<FTPFile>> c) {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setOnSuccessExpressionString("payload.delete()");
    advice.setOnFailureExpressionString("payload + ' failed to upload'");
    advice.setTrapException(true);
    return advice;
}

我的目标是产生一个距离矩阵d,使得d的每个元素都是以g为单位比较每列的成对距离。

[48]: g[0:10,0:10]

array([[ 1,  1,  1,  1,  1,  1,  1,  1,  1, -1],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
      [ 1,  1,  1,  1,  1,  1, -1,  1,  1,  1],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
      [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1, -1],
      [-1, -1,  0, -1, -1, -1, -1, -1, -1,  0],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
      [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1]], dtype=int8)

任何想法都会很棒!谢谢!

3 个答案:

答案 0 :(得分:1)

您可以简单地将功能定义为:

def count_snp_diffs(x, y): 
    return np.count_nonzero((x != y) & (x >= 0) & (y >= 0),axis=0)

然后使用itertools.combinations生成的数组作为索引来调用它,以便所有可能的列组合:

combinations = np.array(list(itertools.combinations(range(g.shape[1]),2)))
dist = count_snp_diffs(g[:,combinations[:,0]], g[:,combinations[:,1]])

此外,如果输出必须存储在一个矩阵中(对于大g而言不会因为只有上三角形将被填充而其余所有内容都将无用信息,这可以用同样的技巧来实现:

d = np.zeros((g.shape[1],g.shape[1]))
combinations = np.array(list(itertools.combinations(range(g.shape[1]),2)))
d[combinations[:,0],combinations[:,1]] = count_snp_diffs(g[:,combinations[:,0]], g[:,combinations[:,1]])

现在,d[i,j]返回列ij之间的距离(而d[j,i]为零)。这种方法依赖于以下事实:数组可以使用包含重复索引的列表或数组进行索引:

a = np.arange(3)+4
a[[0,1,1,1,0,2,1,1]]
# Out
# [4, 5, 5, 5, 4, 6, 5, 5]

以下是对正在发生的事情的一步一步解释。

调用g[:,combinations[:,0]]访问第一列排列中的所有列,生成一个新数组,逐列与使用g[:,combinations[:,1]]生成的数组进行比较。因此,生成了一个布尔数组diff。如果g有3列,则看起来像这样,其中每列都是列0,10,21,2的比较:

[[ True False False]
 [False  True False]
 [ True  True False]
 [False False False]
 [False  True False]
 [False False False]]

最后,添加每列的值:

np.count_nonzero(diff,axis=0)
# Out
# [2 3 0]

此外,由于python中的boolean类继承自整数类(大致False==0True==1,因此请参阅answer“Is False = Python中的= 0和True == 1是一个实现细节还是由语言保证?“以获取更多信息)。 np.count_nonzero为每个True位置添加1,这与np.sum获得的结果相同:

np.sum(diff,axis=0) 
# Out
# [2 3 0]

性能和内存注意事项

对于大型数组,一次使用整个数组可能需要太多内存而且可以获得Memory Error,但是,对于小型或中型阵列,它往往是最快的方法。在某些情况下,按块工作可能很有用:

combinations = np.array(list(itertools.combinations(range(g.shape[1]),2)))
n = len(combinations)
dist = np.empty(n)
# B = np.zeros((g.shape[1],g.shape[1]))
chunk = 200
for i in xrange(chunk,n,chunk):
    dist[i-chunk:i] = count_snp_diffs(g[:,combinations[i-chunk:i,0]], g[:,combinations[i-chunk:i,1]])
    # B[combinations[i-chunk:i,0],combinations[i-chunk:i,1]] = count_snp_diffs(g[:,combinations[i-chunk:i,0]], g[:,combinations[i-chunk:i,1]])
dist[i:] = count_snp_diffs(g[:,combinations[i:,0]], g[:,combinations[i:,1]])
# B[combinations[i:,0],combinations[i:,1]] = count_snp_diffs(g[:,combinations[i:,0]], g[:,combinations[i:,1]])

对于g.shape=(300,N)%%timeit在我的计算机中使用python 2.7,numpy 1.14.2和allel 1.1.10报告的执行时间为:

  • 10列
    • numpy +矩阵存储:107μs
    • numpy + 1D存储:101μs
    • 等位基因:247μs
  • 100列
    • numpy + matrix storage:15.7 ms
    • numpy + 1D存储:16 ms
    • allel:22.6 ms
  • 1000列
    • numpy + matrix storage:1.54 s
    • numpy + 1D storage:1.53 s
    • allel:2.28 s

使用这些数组维度,纯numpy比allel模块更快,但应检查计算时间中的问题。

答案 1 :(得分:0)

您可以使用System.Windows.Data Error: 40 : BindingExpression path error: '(l:GlassButton.Glow)' property not found on 'object' ''Button' (Name='')'. BindingExpression:Path=(l:GlassButton.Glow); DataItem='Button' (Name=''); target element is 'Border' (Name=''); target property is 'Background' (type 'Brush')创建预期的对,然后使用np.dstack在第三轴上应用该功能。

np.apply_along_axis

示例:

new = np.dstack((arr[:,:-1], arr[:, 1:]))
np.apply_along_axis(np.sum, 2, new)

答案 2 :(得分:0)

感谢您的建议! 我刚刚被告知这可以通过scikit-allel:https://scikit-allel.readthedocs.io/en/latest/来定义您自己的距离矩阵,以便在2-D numpy数组中对列的成对组合执行:

dist = allel.pairwise_distance(g, metric=count_snp_diffs)

感谢您的帮助!

http://alimanfoo.github.io/2016/06/10/scikit-allel-tour.html