使用条件范围进行行计数

时间:2015-03-23 19:55:07

标签: python numpy count rows conditional-statements

这是我发布的第一个问题,如果我输错了,请原谅我。

我的目标:我正在尝试计算满足条件范围的行数。各个数组元素表示峰值出现的时间(以秒为单位)。输入数据中的每一行代表一个活动/发射单元。我想计算每分钟活动单元(行)的数量(迭代60秒)。

我的数据:我的输入数据(T)是从整数数组导入的txt,并且有几个0,我不想在其他操作中计算。我在下面复制了这些数据的一部分。

我的问题:我的具体问题是我没有看到我的尝试有什么问题(如下),但由于数组相当小,我可以手动检查其真实性输出。无论出于何种原因,True参数从“正确”迭代开始,但随后保持为True(当它们应返回false时),直到循环中出现另一个True。然后输出保持'正确'错误。这让我发疯,我非常感谢任何帮助。以下尝试甚至不会尝试对行进行求和,而只是返回正确的True / False参数排列。

import numpy as np

T = T.astype(float)
T[T==0] = np.nan
for x in xrange(0, 1321, 60):
    RowSum = np.any(T>x, axis = 1) & np.any(T<x+60, axis = 1)
    print RowSum

输入数据:

array([[  111.,   184.,   221.,   344.,   366.,     0.,     0.,     0.,
0.,     0.,     0.],
[  408.,   518.,   972.,  1165.,  1186.,     0.,     0.,     0.,
0.,     0.,     0.],
[  208.,   432.,  1290.,  1321.,     0.,     0.,     0.,     0.,
0.,     0.,     0.],
[  553.,   684.,   713.,   888.,  1012.,  1108.,  1134.,     0.,
0.,     0.,     0.],
[  285.,   552.,  1159.,  1183.,     0.,     0.,     0.,     0.,
0.,     0.,     0.],
[  304.,   812.,   852.,     0.,     0.,     0.,     0.,     0.,
0.,     0.,     0.]])

1 个答案:

答案 0 :(得分:1)

E先生是对的 - np.histogram可能是最简单的方法:

import numpy as np

# array of spike times
t = np.array([[ 111,  184,  221,  344,  366,    0,    0,    0,    0,    0,    0],
              [ 408,  518,  972, 1165, 1186,    0,    0,    0,    0,    0,    0],
              [ 208,  432, 1290, 1321,    0,    0,    0,    0,    0,    0,    0],
              [ 553,  684,  713,  888, 1012, 1108, 1134,    0,    0,    0,    0],
              [ 285,  552, 1159, 1183,    0,    0,    0,    0,    0,    0,    0],
              [ 304,  812,  852,    0,    0,    0,    0,    0,    0,    0,    0]],
              dtype=np.float)

# 60 second time bins
bins = np.arange(0, t.max() + 60, 60)

# get the total number of spikes in each 60 second bin over all rows (cells). we 
# can treat t as 1D since we don't care which spike times correspond to which
# cell.
counts, edges = np.histogram(t[t != 0], bins)

print(bins)
# [    0.    60.   120.   180.   240.   300.   360.   420.   480.   540.
#    600.   660.   720.   780.   840.   900.   960.  1020.  1080.  1140.
#   1200.  1260.  1320.  1380.]

print(counts)
# [0 1 0 3 1 2 2 1 1 2 0 2 0 1 2 0 2 0 2 4 0 1 1]

所以我们在0到60秒之间总共有0个峰值,在60到120秒之间有一个峰值等等。顺便说一下,我建议你不要使用T作为变量名 - 它可能会导致混乱,因为在numpy .T用于获得数组的转置。

要获得每个单元格的峰值计数,您需要遍历t行:

cell_counts = np.empty((t.shape[0], bins.shape[0] - 1), np.int)
for ii, row in enumerate(t):
    cell_counts[ii], edges = np.histogram(row[row != 0], bins)

print(cell_counts)
# [[0 1 0 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
#  [0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 2 0 0 0]
#  [0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1]
#  [0 0 0 0 0 0 0 0 0 1 0 2 0 0 1 0 1 0 2 0 0 0 0]
#  [0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 0 0]
#  [0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0]]

更新

如果我理解正确,您想知道每个60秒时间间隔内飙升的细胞总数,无论每个细胞发出的穗数是多少。一种简单的方法是将cell_counts数组中的值截断为1,然后沿行求和:

total_active_cells = (cell_counts > 0).sum(0)

print(total_active_cells)
# [0 1 0 2 1 2 2 1 1 2 0 1 0 1 2 0 2 0 1 2 0 1 1]