我想在我用Python模拟的100个bin信号中添加一些随机噪声 - 使其更加真实.
在基本层面上,我的第一个想法是逐个bin,只是在一定范围之间生成一个随机数,并从信号中加上或减去它.
我希望(因为这是python)可能有更聪明的方法通过numpy或其他东西来做到这一点.(我认为理想情况下,从高斯分布中提取并添加到每个bin中的数字也会更好.)
感谢您的任何回复.
我只是在计划我的代码阶段,所以我没有任何东西要展示.我只是觉得可能有更复杂的方法来产生噪音.
就输出而言,如果我有10个具有以下值的区间:
Bin 1:1 Bin 2:4 Bin 3:9 Bin 4:16 Bin 5:25 Bin 6:25 Bin 7:16 Bin 8:9 Bin 9:4 Bin 10:1
我只是想知道是否有一个预定义的函数可以添加噪音给我类似的东西:
Bin 1:1.13 Bin 2:4.21 Bin 3:8.79 Bin 4:16.08 Bin 5:24.97 Bin 6:25.14 Bin 7:16.22 Bin 8:8.90 Bin 9:4.02 Bin 10:0.91
如果没有,我将逐个bin地添加从高斯分布中选择的数字到每个.
谢谢.
它实际上是我正在模拟的射电望远镜发出的信号.我希望能够最终选择模拟的信噪比.
Aka*_*all 99
您可以生成噪声阵列,并将其添加到信号中
import numpy as np
noise = np.random.normal(0,1,100)
# 0 is the mean of the normal distribution you are choosing from
# 1 is the standard deviation of the normal distribution
# 100 is the number of elements you get in array noise
Run Code Online (Sandbox Code Playgroud)
Noe*_*ans 55
......对于那些像我一样的人,他们的学习曲线非常早,
import numpy as np
pure = np.linspace(-1, 1, 100)
noise = np.random.normal(0, 1, pure.shape)
signal = pure + noise
Run Code Online (Sandbox Code Playgroud)
tmc*_*itt 28
对于那些试图在SNR和numpy生成的普通随机变量之间建立联系的人:
[1] ,请紧记P是平均功率。
或dB:
[2]
在这种情况下,我们已经有一个信号,并且我们想产生噪声以提供所需的SNR。
虽然噪音可能会有不同的味道取决于你模拟什么,一个良好的开端(尤其是这个射电望远镜的例子)是加性高斯白噪声(AWGN) 。如前面的答案所述,要对AWGN建模,您需要在原始信号中添加零均值高斯随机变量。该随机变量的方差将影响平均噪声功率。
对于高斯随机变量X,平均功率 也称为第二时刻,是
[3]
所以对于白噪声, 然后平均功率等于方差
。
在python中进行建模时,您可以
1.根据所需的SNR和一组现有测量值计算方差,如果您希望测量结果具有相当一致的幅度值,则可以使用该方法。
2.或者,您可以将噪声功率设置为已知水平,以匹配接收器噪声。可以通过将望远镜对准自由空间并计算平均功率来测量接收器噪声。
无论哪种方式,重要的是要确保将噪声添加到信号中,并在线性空间而不是dB单位中求平均值。
这是一些生成信号并绘制电压,功率(瓦)和功率(dB)的代码:
# Signal Generation
# matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(1, 100, 1000)
x_volts = 10*np.sin(t/(2*np.pi))
plt.subplot(3,1,1)
plt.plot(t, x_volts)
plt.title('Signal')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
x_watts = x_volts ** 2
plt.subplot(3,1,2)
plt.plot(t, x_watts)
plt.title('Signal Power')
plt.ylabel('Power (W)')
plt.xlabel('Time (s)')
plt.show()
x_db = 10 * np.log10(x_watts)
plt.subplot(3,1,3)
plt.plot(t, x_db)
plt.title('Signal Power in dB')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
这是根据所需的SNR添加AWGN的示例:
# Adding noise using target SNR
# Set a target SNR
target_snr_db = 20
# Calculate signal power and convert to dB
sig_avg_watts = np.mean(x_watts)
sig_avg_db = 10 * np.log10(sig_avg_watts)
# Calculate noise according to [2] then convert to watts
noise_avg_db = sig_avg_db - target_snr_db
noise_avg_watts = 10 ** (noise_avg_db / 10)
# Generate an sample of white noise
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(noise_avg_watts), len(x_watts))
# Noise up the original signal
y_volts = x_volts + noise_volts
# Plot signal with noise
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
# Plot in dB
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise (dB)')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
这是一个基于已知噪声功率添加AWGN的示例:
# Adding noise using a target noise power
# Set a target channel noise power to something very noisy
target_noise_db = 10
# Convert to linear Watt units
target_noise_watts = 10 ** (target_noise_db / 10)
# Generate noise samples
mean_noise = 0
noise_volts = np.random.normal(mean_noise, np.sqrt(target_noise_watts), len(x_watts))
# Noise up the original signal (again) and plot
y_volts = x_volts + noise_volts
# Plot signal with noise
plt.subplot(2,1,1)
plt.plot(t, y_volts)
plt.title('Signal with noise')
plt.ylabel('Voltage (V)')
plt.xlabel('Time (s)')
plt.show()
# Plot in dB
y_watts = y_volts ** 2
y_db = 10 * np.log10(y_watts)
plt.subplot(2,1,2)
plt.plot(t, 10* np.log10(y_volts**2))
plt.title('Signal with noise')
plt.ylabel('Power (dB)')
plt.xlabel('Time (s)')
plt.show()
Run Code Online (Sandbox Code Playgroud)
对于那些想要将噪声添加到pandas数据帧中加载的多维数据集或者甚至是numpy ndarray的人来说,这是一个例子:
import pandas as pd
# create a sample dataset with dimension (2,2)
# in your case you need to replace this with
# clean_signal = pd.read_csv("your_data.csv")
clean_signal = pd.DataFrame([[1,2],[3,4]], columns=list('AB'), dtype=float)
print(clean_signal)
"""
print output:
A B
0 1.0 2.0
1 3.0 4.0
"""
import numpy as np
mu, sigma = 0, 0.1
# creating a noise with the same dimension as the dataset (2,2)
noise = np.random.normal(mu, sigma, [2,2])
print(noise)
"""
print output:
array([[-0.11114313, 0.25927152],
[ 0.06701506, -0.09364186]])
"""
signal = clean_signal + noise
print(signal)
"""
print output:
A B
0 0.888857 2.259272
1 3.067015 3.906358
"""
Run Code Online (Sandbox Code Playgroud)
小智 5
在现实生活中,您希望模拟带有白噪声的信号。您应该向信号添加具有正态高斯分布的随机点。如果我们谈论的设备的灵敏度以单位/SQRT(Hz) 为单位,那么您需要设计您的点的标准偏差。在这里,我给出了函数“white_noise”来为您执行此操作,代码的其余部分是演示并检查它是否执行了应有的操作。
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
"""
parameters:
rhp - spectral noise density unit/SQRT(Hz)
sr - sample rate
n - no of points
mu - mean value, optional
returns:
n points of noise signal with spectral noise density of rho
"""
def white_noise(rho, sr, n, mu=0):
sigma = rho * np.sqrt(sr/2)
noise = np.random.normal(mu, sigma, n)
return noise
rho = 1
sr = 1000
n = 1000
period = n/sr
time = np.linspace(0, period, n)
signal_pure = 100*np.sin(2*np.pi*13*time)
noise = white_noise(rho, sr, n)
signal_with_noise = signal_pure + noise
f, psd = signal.periodogram(signal_with_noise, sr)
print("Mean spectral noise density = ",np.sqrt(np.mean(psd[50:])), "arb.u/SQRT(Hz)")
plt.plot(time, signal_with_noise)
plt.plot(time, signal_pure)
plt.xlabel("time (s)")
plt.ylabel("signal (arb.u.)")
plt.show()
plt.semilogy(f[1:], np.sqrt(psd[1:]))
plt.xlabel("frequency (Hz)")
plt.ylabel("psd (arb.u./SQRT(Hz))")
#plt.axvline(13, ls="dashed", color="g")
plt.axhline(rho, ls="dashed", color="r")
plt.show()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
120983 次 |
最近记录: |