用Python在Pandas中快速子集化

时间:2018-11-12 18:25:24

标签: python pandas performance indexing subset

我正在运行一个循环数百万次,并且我需要在每个循环中分配不同数量的数据。我有一个数据帧,该数据帧有两列,时间(是一个时间序列)和电极,它表示当时发射的任何电极在1-64之间的数字。

time    electrode
 0          1
 1          43
 2          45
 3          12
 4          7

在每个循环中,我都需要对数据进行子集化,例如:

num_electrodes = []
window_size = 5
index = 0
while index < len(data['time']) - interval_size:
    start = data['time'][index]
    end = data['time'][index+window_size]
    window_data = data[(data['time'] >= start) & (data['time'] < end)]
    num_electrodes.append(len(window_data['electrode'].unique()))

这里的代码最慢的部分是在下面的代码中子集数据帧并创建一个新的数据帧。

window_data = data[(data['time'] >= start) & (data['time'] < end)]

这有什么好的选择吗?

3 个答案:

答案 0 :(得分:1)

按时间排序,然后可以使用.loc在窗口的开头和结尾访问索引,然后选择一系列索引作为子集。

将df的索引设置为时间序列,然后使用df.index.get_loc(beginning_window)min(df.index.get_loc(beginning_window+window+1)) -1获取索引范围。

最小值代表非唯一索引。

然后使用.iloc选择该范围。

那会大大加快速度。

答案 1 :(得分:0)

假设您的数据是按时间排序的,则只需将电极按5分组即可。然后set会比np.unique快:

size=10**6
window_size=5
electrodes = np.random.randint(0,64,size)
electrodes_by_5 = electrodes.reshape(-1,window_size)

nb_electrodes=np.apply_along_axis(lambda arr:len(set(arr)),1,electrodes_by_5)

输出:

In [463]: electrodes[:10]
Out[463]: array([13, 13, 23, 20,  5, 30,  9,  6, 28, 11])

In [464]: electrodes_by_5[:2]
Out[464]: 
array([[13, 13, 23, 20,  5],
       [30,  9,  6, 28, 11]])

In [465]: nb_electrodes[:2]
Out[465]: array([4, 5])

答案 2 :(得分:0)

所以我通过切换到numpy.ndarray解决了这个问题,它比使用iloc进行索引无限快。