【问题标题】:How to drop data above a certain frequency in a histogram/dataset?如何在直方图/数据集中删除高于特定频率的数据?
【发布时间】:2021-04-04 23:30:56
【问题描述】:

为了让事情更清楚,我不想从直方图中删除整个 bin,我只想删除一些数据,使其低于所需的频率。图像中的线显示了我想要的最大频率

对于上下文,我有一个包含多个角度的数据集。在使用的数据方面,我的问题与Remove data above threshold in histogram 这里提出的问题非常相似,但与链接中的问题不同,我不想摆脱数据,只是减少它。

我可以直接从直方图中执行此操作,还是只需要删除数据集中的一些数据?

编辑(抱歉,我对这里的编码和格式不熟悉): 这是我尝试过的解决方案

bns = 30
hist, bins  = np.histogram(dataset['Steering'], bins= bns)
removeddata = []

spb = 700
for j in range(bns):
    rdata = []
    for i in range(len(dataset['Steering'])):
        if dataset['Steering'][i] >= bins[j] and dataset['Steering'][i] <= 
        bins[j+1]:
            rdata.append(i)
    rdata = shuffle(rdata)
    rdata = rdata[spb:]
    removeddata.extend(rdata)


print('removed:', len(removeddata))
dataset.drop(dataset.index[removeddata], inplace = True)
print ('remaining:', len(dataset))



center = (bins[:-1] + bins[1:])*0.5
plt.bar(center,hist,width=0.05)
plt.show()

这是其他人的解决方案,但似乎对他们有用。即使直接复制,它仍然会抛出错误。我得到的错误是“ValueError:一个系列的真值是不明确的。使用a.empty,a.bool(),a.item(),a.any()或a.all()”,我试图将 'and' 更改为 & 并得到错误“TypeError: Cannot perform 'rand_' with a dtyped [float64] array and scalar of type [bool]”。不确定 this 到底指的是什么,但指向 if 语句所在的行。检查了所有东西的dtype,它们都是float64类型,所以不确定我的下一步

【问题讨论】:

  • 听起来你想要一个低通滤波器?
  • 谢谢,但不,我不这么认为,有问题的角度是转向角度。参考我提供的链接,我基本上与提出问题的用户具有完全相同的设置,但提供答案的用户对问题的解释不同。

标签: python histogram


【解决方案1】:

该解决方案考虑了删除超过频率阈值的原始输入数据的明确要求。我留下了我的另一个答案,因为它足够简单和不同,可能对其他用户有用。

为了澄清,这个答案产生了一个新的一维数据数组,其中元素更少,然后根据该新数据绘制直方图。在移除元素之前对数据进行混洗(以防输入数据被预先排序),以防止从每个 bin 的低端或高端丢弃数据时出现偏差。

import numpy as np
import matplotlib.pyplot as plt
from random import shuffle


def remove_gated_val_recursive(idx, to_gate_lst, bins_lst, data_lst):
    if to_gate_lst[idx] == 0:
        return(data_lst)
    else:
        bin_min, bin_max = bins_lst[idx], bins_lst[idx + 1]
        for i in range(len(data_lst)):
            if bin_min <= data_lst[i] < bin_max:
                del data_lst[i]
                to_gate_lst[idx] -= 1
                break
        return remove_gated_val_recursive(idx, to_gate_lst, bins_lst, data_lst)

    
threshold = 80

fig, ax1 = plt.subplots()
ax1.set_title("Some data")

np.random.seed(30)
data = np.random.randn(1000)

num_bins = 23

raw_hist, raw_bins = np.histogram(data, num_bins)

to_gate = []
for i in range(len(raw_hist)):
    if raw_hist[i] > threshold:
        to_gate.append(raw_hist[i] - threshold)
    else:
        to_gate.append(0)

data_lst = list(data)
shuffle(data_lst)

for idx in range(len(raw_hist)):
    remove_gated_val_recursive(idx, to_gate, raw_bins, data_lst)
    
new_data = np.array(data_lst)
hist, bins = np.histogram(new_data, num_bins)

width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) * 0.5
ax1.bar(center, hist, align='center', width=width)

plt.show()

给出以下直方图,绘制自 new_data 数组。

【讨论】:

  • 这正是我的意思,非常感谢。唯一的问题是我的数据意味着错误:“RecursionError:比较中超出最大递归深度”被抛出,但是有一种方法可以解决这个问题,当我到达那里时我会分享
【解决方案2】:

此答案不会重新分类或重新集中数据,但我相信它通常可以实现您的要求。根据您链接的帖子的所选答案中的示例,我编辑 hist 数组,以便原始输入数据不会更改,因为您指出是您的首选解决方案:

import numpy as np
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1,2)
ax1.set_title("Some data")
ax2.set_title("Gated data < threshold")

np.random.seed(10)
data = np.random.randn(1000)

num_bins = 23
avg_samples_per_bin = 200

hist, bins = np.histogram(data, num_bins)
width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) * 0.5
ax1.bar(center, hist, align='center', width=width)

threshold = 80

gated = np.empty([len(hist)], dtype=np.int64)
for i in range(len(hist)):
    if hist[i] > threshold:
        gated[i] = threshold
    else:
        gated[i] = hist[i]

ax2.bar(center, gated, align="center", width=width)

plt.show()

给了

【讨论】:

  • 非常感谢!这通常是我在直方图中寻找的内容,但我忘记明确表示我希望新数据集成为新直方图中显示的内容。即,现在可以从原始输入中删除所有被限制的数据,这样我就可以正常绘制直方图。很抱歉,我没有说得足够清楚,对我来说已经晚了,但我感谢您的帮助。我已经编辑了我的主要问题,以显示我从其他人那里尝试过的解决方案以及我遇到了哪些错误
猜你喜欢
  • 2018-12-21
  • 1970-01-01
  • 2016-03-28
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
相关资源
最近更新 更多