快速从 Python 中的列表中删除异常值?
Quickly remove outliers from list in Python?
我有很多时间和温度值的长列表,其结构如下:
list1 = [[1, 72], [2, 72], [3, 73], [4, 72], [5, 74], [6, 73], [7, 71], [8, 92], [9, 73]]
一些 time/temperature 对是数据中不正确的尖峰。例如,在时间 8 中,它飙升至 92 度。我想摆脱这些温度值的突然跳跃或骤降。
为此,我编写了以下代码(我删除了不需要的内容,只复制了删除 spikes/outliers 的部分):
outlierpercent = 3
for i in values:
temperature = i[1]
index = values.index(i)
if index > 0:
prevtemp = values[index-1][1]
pctdiff = (temperature/prevtemp - 1) * 100
if abs(pctdiff) > outlierpercent:
outliers.append(i)
虽然这可行(我可以将它被视为尖峰所需的最小百分比差异设置为 outlierpercent
),但它需要很长时间(每个列表 5-10 分钟)。我的列表非常长(每个大约 500 万个数据点),而且我有数百个列表。
我想知道是否有更快的方法?我主要关心的是时间。还有其他类似的问题,但是,对于这种结构的超长列表,它们似乎效率不高,所以我不确定该怎么做!谢谢!
outlierpercent = 3
for index in range(1, len(values)):
temperature = values[index][1]
prevtemp = values[index-1][1]
pctdiff = (temperature/prevtemp - 1) * 100
if abs(pctdiff) > outlierpercent:
outliers.append(index)
随着时间的推移,这应该会做得更好
更新:
只有第一个异常值被移除的问题是因为在我们移除异常值之后,在下一次迭代中,我们正在比较移除的异常值(prevtemp = values[index-1][1]
)的温度。
我相信你可以通过更好地处理之前的温度来避免这种情况。像这样:
outlierpercent = 3
prevtemp = values[0][1]
for index in range(1, len(values)):
temperature = values[index][1]
pctdiff = (temperature/prevtemp - 1) * 100
# outlier - add to list and don't update prev temp
if abs(pctdiff) > outlierpercent:
outliers.append(index)
# valid temp, update prev temp
else:
prevtemp = values[index-1][1]
使用 Numpy 加速计算
有
values = [[1, 72], [2, 72], [3, 73], [4, 72], [5, 74], [6, 73], [7, 71], [8, 92], [9, 73]]
Numpy 代码
# Convert list to Numpy array
a = np.array(values)
# Calculate absolute percent difference of temperature
b = np.diff(a[:, 1])*100/a[:-1, 1]
# List of outliers
outlier_indices = np.where(np.abs(b) > outlierpercent)
if outlier_indices:
print(a[outlier_indices[0]+1]) # add one since b is is one short due to
# computing difference
# Output: List of outliers same as original code
[[ 8 92]
[ 9 73]]
这应该生成两个列表,有效列表和离群值列表。
我试图将数学运算保持在最低限度以提高速度。
请原谅任何打字错误,这是键盘组成的,未经测试。
lolim=None
outliers=[]
outlierpercent=3.0
lower_mult=(100.0-outlierpercent)/100.0
upper_mult=(100.0+outlierpercent)/100.0
for index,temp in values
if lolim is None:
valids=[[index,temp]] # start the valid list
lolim,hilim=[lower_mult,upper_mult]*temp # create initial range
else:
if lolim <= temp <= hilim:
valids.append([index,temp]) # new valid entry
lolim,hilim=[lower_mult,upper_mult]*temp # update range
else:
outliers.append([index,temp]) # save outliers, keep old range
我有很多时间和温度值的长列表,其结构如下:
list1 = [[1, 72], [2, 72], [3, 73], [4, 72], [5, 74], [6, 73], [7, 71], [8, 92], [9, 73]]
一些 time/temperature 对是数据中不正确的尖峰。例如,在时间 8 中,它飙升至 92 度。我想摆脱这些温度值的突然跳跃或骤降。
为此,我编写了以下代码(我删除了不需要的内容,只复制了删除 spikes/outliers 的部分):
outlierpercent = 3
for i in values:
temperature = i[1]
index = values.index(i)
if index > 0:
prevtemp = values[index-1][1]
pctdiff = (temperature/prevtemp - 1) * 100
if abs(pctdiff) > outlierpercent:
outliers.append(i)
虽然这可行(我可以将它被视为尖峰所需的最小百分比差异设置为 outlierpercent
),但它需要很长时间(每个列表 5-10 分钟)。我的列表非常长(每个大约 500 万个数据点),而且我有数百个列表。
我想知道是否有更快的方法?我主要关心的是时间。还有其他类似的问题,但是,对于这种结构的超长列表,它们似乎效率不高,所以我不确定该怎么做!谢谢!
outlierpercent = 3
for index in range(1, len(values)):
temperature = values[index][1]
prevtemp = values[index-1][1]
pctdiff = (temperature/prevtemp - 1) * 100
if abs(pctdiff) > outlierpercent:
outliers.append(index)
随着时间的推移,这应该会做得更好
更新:
只有第一个异常值被移除的问题是因为在我们移除异常值之后,在下一次迭代中,我们正在比较移除的异常值(prevtemp = values[index-1][1]
)的温度。
我相信你可以通过更好地处理之前的温度来避免这种情况。像这样:
outlierpercent = 3
prevtemp = values[0][1]
for index in range(1, len(values)):
temperature = values[index][1]
pctdiff = (temperature/prevtemp - 1) * 100
# outlier - add to list and don't update prev temp
if abs(pctdiff) > outlierpercent:
outliers.append(index)
# valid temp, update prev temp
else:
prevtemp = values[index-1][1]
使用 Numpy 加速计算
有
values = [[1, 72], [2, 72], [3, 73], [4, 72], [5, 74], [6, 73], [7, 71], [8, 92], [9, 73]]
Numpy 代码
# Convert list to Numpy array
a = np.array(values)
# Calculate absolute percent difference of temperature
b = np.diff(a[:, 1])*100/a[:-1, 1]
# List of outliers
outlier_indices = np.where(np.abs(b) > outlierpercent)
if outlier_indices:
print(a[outlier_indices[0]+1]) # add one since b is is one short due to
# computing difference
# Output: List of outliers same as original code
[[ 8 92]
[ 9 73]]
这应该生成两个列表,有效列表和离群值列表。
我试图将数学运算保持在最低限度以提高速度。
请原谅任何打字错误,这是键盘组成的,未经测试。
lolim=None
outliers=[]
outlierpercent=3.0
lower_mult=(100.0-outlierpercent)/100.0
upper_mult=(100.0+outlierpercent)/100.0
for index,temp in values
if lolim is None:
valids=[[index,temp]] # start the valid list
lolim,hilim=[lower_mult,upper_mult]*temp # create initial range
else:
if lolim <= temp <= hilim:
valids.append([index,temp]) # new valid entry
lolim,hilim=[lower_mult,upper_mult]*temp # update range
else:
outliers.append([index,temp]) # save outliers, keep old range