【发布时间】:2020-07-29 14:46:11
【问题描述】:
我正在寻找一种算法,它允许我搜索和获取系列中所有间隙(nans)的索引,其中索引是指“分区”的开始和结束。我找不到解决方案,所以我最终使用了自己创建的代码。一切都很好,除了这两种方法似乎有点慢。我想知道是否有办法优化代码。
我尝试了两种方法。第一个是对所有索引进行简单的 for 循环并检查是否继续。另一个删除 nan 值,然后再次使用 List Comprehension 检查是否继续。后一种方法更快。
我想知道是否有更好的方法来提高速度,或者我错过了一些已经内置的东西。谢谢。
数据:
import numpy as np
import pandas as pd
# Create an object with sample data
w = pd.Series(np.sin(2*np.pi*np.linspace(0,1,2880)))
# Insert a few gaps with missing values
for i in np.arange(0, 1500, 200):
w.loc[w.index[0]+i:w.index[0]+i+100] = np.nan
w.loc[2880-100:] = np.nan```
第一种方法:
# Get indices
# `l_nans` stores the first and the last index of each gap
t0 = time()
for c in range(1000):
i_nans = w[w.isnull()].index.to_numpy()
len_nans = i_nans.shape[0]
f, l, p, n = np.nan, np.nan, np.nan, np.nan
l_nans = list()
i = 0
for i, e in enumerate(i_nans.tolist()):
if not np.isnan(n):
p = n
n = e
if np.isnan(f):
f = e
if (n-p) > 1:
l = p
l_nans.append((f, l))
f, l = e, np.nan
if i == len_nans-1:
l = n
l_nans.append((f, l))
print(l_nans)
print(time() - t0)
[(0, 100), (200, 300), (400, 500), (600, 700), (800, 900), (1000, 1100), (1200, 1300), (1400, 1500), (2780, 2879)]
3.1106319427490234
第二种方法:
# Get indices
# `l_nans` stores the first and the last index of each gap
t0 = time()
for c in range(1000):
v = w.drop(w[w.isnull()].index, axis=0)
l_nans = [(e[0]+1, e[1]-1) for e in zip(v.index[:-1], v.index[1:]) if e[1]-e[0] > 1]
if not any(v.index.isin([w.index[0]])):
l_nans.insert(0, (0, v.first_valid_index()-1))
if not any(v.index.isin([w.index[-1]])):
l_nans.append((v.last_valid_index()+1, w.index[-1]))
print(l_nans)
print(time() - t0)
[(0, 100), (200, 300), (400, 500), (600, 700), (800, 900), (1000, 1100), (1200, 1300), (1400, 1500), (2780, 2879)]
1.8505527973175049
编辑。
我意识到我的真实数据的某些部分具有单个 nan 值。所以示例数据如下:
import numpy as np
import pandas as pd
# Create an object with sample data
w = pd.Series(np.sin(2*np.pi*np.linspace(0,1,2880)))
# Insert a few gaps with missing values
for i in np.arange(0, 1500, 200):
w.loc[w.index[0]+i:w.index[0]+i+100] = np.nan
w.loc[2880-100:] = np.nan
w.loc[1600] = np.nan
w.loc[1700] = np.nan
【问题讨论】:
-
你能贴几行df测试数据和想要的结果吗?
-
@ZarakiKenpachi
w这里是测试数据,想要的结果是每个方法下面的元组列表。 -
我稍微改变了问题并添加了一些 cmets 以提高清晰度。
w(pandasSeries对象)包含带有NaNs 的样本数据,l_nans是一个列表对象,用于存储每个间隙的所有范围索引。