अजगर में एक सिग्नल के लिए शोर जोड़ना


95

मैं कुछ 100 बिन सिग्नल में कुछ यादृच्छिक शोर जोड़ना चाहता हूं जिसे मैं पायथन में अनुकरण कर रहा हूं - इसे और अधिक यथार्थवादी बनाने के लिए।

एक बुनियादी स्तर पर, मेरा पहला विचार बिन द्वारा बिन जाना और बस एक निश्चित सीमा के बीच एक यादृच्छिक संख्या उत्पन्न करना और संकेत से इसे जोड़ना या घटाना था।

मैं उम्मीद कर रहा था (जैसा कि यह अजगर है) कि ऐसा करने के लिए और अधिक बुद्धिमान तरीका हो सकता है कि वह सुन्न हो या कुछ और। (मुझे लगता है कि आदर्श रूप से एक गौसियन वितरण से तैयार की गई संख्या और प्रत्येक बिन में जोड़ा गया बेहतर भी होगा।)

किसी भी उत्तर की अग्रिम धन्यवाद।


मैं अभी अपने कोड की योजना बना रहा हूं, इसलिए मेरे पास दिखाने के लिए कुछ भी नहीं है। मैं बस सोच रहा था कि शोर पैदा करने का एक और अधिक परिष्कृत तरीका हो सकता है।

आउटपुट के संदर्भ में, अगर मेरे पास निम्नलिखित मानों के साथ 10 डिब्बे थे:

बिन 1: 1 बिन 2: 4 बिन 3: 9 बिन 4: 16 बिन 5: 25 बिन 6: 25 बिन 7: 16 बिन 8: 9 बिन 9: 4 बिन 10: 1

मुझे आश्चर्य हुआ कि क्या कोई पूर्व-परिभाषित समारोह था जो मुझे कुछ देने के लिए शोर जोड़ सकता है:

बिन 1: 1.13 बिन 2: 4.21 बिन 3: 8.79 बिन 4: 16.08 बिन 5: 24.97 बिन 6: 25.14 बिन 7: 16.22 बिन 8: 8.90 बिन 9: 4.02 बिन 10: 0.91

यदि नहीं, तो मैं बस बिन-बाय-बिन जाऊंगा और गॉसियन डिस्ट्रीब्यूशन से चुने गए नंबर को हर एक में जोड़ दूंगा।

धन्यवाद।


यह वास्तव में एक रेडियो टेलीस्कोप से संकेत है कि मैं अनुकरण कर रहा हूं। मैं अंततः अपने सिमुलेशन के शोर अनुपात के लिए संकेत का चयन करने में सक्षम होना चाहता हूं।


2
कृपया अपने द्वारा दिखाए गए कोड, या एक विशिष्ट समस्या का सामना कर रहे हैं। नमूना इनपुट और वांछित आउटपुट एक लंबा रास्ता तय करेगा।
— gddc 17

2
यह किस तरह का संकेत है? आप किस तरह का शोर मचाना चाहते हैं? "यथार्थवादी" संकेत के प्रकार पर निर्भर करता है। उदाहरण के लिए, शोर शोर छवि शोर के समान नहीं है।
— डिएगो बस्च

जवाबों:


126

आप एक शोर सरणी उत्पन्न कर सकते हैं, और इसे अपने सिग्नल में जोड़ सकते हैं

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

17
कुछ संदर्भों में, यह एक शोर सरणी को जोड़ने के बजाय एक शोर सरणी (1 के आसपास केंद्रित) द्वारा आपके सिग्नल को गुणा करने के लिए अधिक समझदार हो सकता है, लेकिन निश्चित रूप से उस शोर की प्रकृति पर निर्भर करता है जिसे आप अनुकरण करने की कोशिश कर रहे हैं।
— एडवर्ड लपर

69

... और उन लोगों के लिए - जो मुझे पसंद करते हैं - उनकी बहुत जल्दी सीखने की अवस्था है,

import numpy as np
pure = np.linspace(-1, 1, 100)
noise = np.random.normal(0, 1, 100)
signal = pure + noise

59

उन लोगों के लिए जो एसएनआर और सामान्य रैंडम वैरिएबल के बीच संबंध बनाने की कोशिश कर रहे हैं :

[१] एसएनआर अनुपात, जहाँ यह ध्यान रखना महत्वपूर्ण है कि पी औसत शक्ति है।

या डीबी में:
[२]SNR dB2

इस मामले में, हमारे पास पहले से ही एक संकेत है और हम हमें वांछित एसएनआर देने के लिए शोर उत्पन्न करना चाहते हैं।

जबकि शोर अलग-अलग स्वादों में आ सकता है जो आप मॉडलिंग कर रहे हैं, इस पर निर्भर करता है कि एक अच्छी शुरुआत (विशेष रूप से इस रेडियो टेलीस्कोप उदाहरण के लिए) एडिटिव व्हाइट गॉसियन शोर (AWGN) है । जैसा कि पिछले उत्तरों में कहा गया है, AWGN को मॉडल करने के लिए आपको अपने मूल सिग्नल में शून्य-माध्य गॉसियन रैंडम वैरिएबल जोड़ना होगा। उस यादृच्छिक चर का विचलन औसत शोर शक्ति को प्रभावित करेगा ।

एक गाऊसी यादृच्छिक चर X के लिए, औसत शक्ति एपि, जिसे दूसरे क्षण के रूप में भी जाना जाता है ,
[3] भूतपूर्व

तो सफेद शोर के लिए, भूतपूर्वऔर औसत शक्ति तब विचरण के बराबर होती है भूतपूर्व।

जब यह अजगर में मॉडलिंग करता है, तो आप या तो
1. वांछित वांछित SNR और मौजूदा मापों के एक सेट के आधार पर विचरण की गणना कर सकते हैं , जो तब काम करेगा जब आप अपने माप से काफी सुसंगत आयाम मानों की अपेक्षा करेंगे।
2. वैकल्पिक रूप से, आप रिसीवर के शोर जैसी किसी चीज़ से मेल खाने के लिए ध्वनि शक्ति को ज्ञात स्तर पर सेट कर सकते हैं। टेलीस्कोप को मुक्त स्थान में इंगित करके और औसत शक्ति की गणना करके रिसीवर के शोर को मापा जा सकता है।

किसी भी तरह से, यह सुनिश्चित करना महत्वपूर्ण है कि आप अपने सिग्नल में शोर जोड़ते हैं और रैखिक अंतरिक्ष में औसत लेते हैं और डीबी इकाइयों में नहीं।

सिग्नल और प्लॉट वोल्टेज, वाट्स में पावर और डीबी में पावर उत्पन्न करने के लिए यहां कुछ कोड दिए गए हैं:

# 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()

उत्पन्न संकेत

यहां वांछित 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()

लक्ष्य एसएनआर के साथ सिग्नल

और यहाँ एक ज्ञात शोर शक्ति के आधार पर 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()

लक्ष्य शोर स्तर के साथ संकेत


8

उन लोगों के लिए जो पंडों के डेटाफ्रेम या यहां तक ​​कि एक सुन्न 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
""" 

1

वास्तविक जीवन में आप सफेद शोर के साथ एक संकेत अनुकरण करना चाहते हैं। आपको अपने सिग्नल को रैंडम पॉइंट्स से जोड़ना चाहिए, जिसमें नॉर्मल गाऊसी डिस्ट्रीब्यूशन हो। यदि हम यूनिट / 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()

शोर के साथ संकेत

PSD


0

ऊपर भयानक जवाब। मुझे हाल ही में सिम्युलेटेड डेटा उत्पन्न करने की आवश्यकता थी और यही वह है जिसका उपयोग करके मैं उतरा। दूसरों के लिए भी मददगार,

import logging
__name__ = "DataSimulator"
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

import numpy as np
import pandas as pd

def generate_simulated_data(add_anomalies:bool=True, random_state:int=42):
    rnd_state = np.random.RandomState(random_state)
    time = np.linspace(0, 200, num=2000)
    pure = 20*np.sin(time/(2*np.pi))

    # concatenate on the second axis; this will allow us to mix different data 
    # distribution
    data = np.c_[pure]
    mu = np.mean(data)
    sd = np.std(data)
    logger.info(f"Data shape : {data.shape}. mu: {mu} with sd: {sd}")
    data_df = pd.DataFrame(data, columns=['Value'])
    data_df['Index'] = data_df.index.values

    # Adding gaussian jitter
    jitter = 0.3*rnd_state.normal(mu, sd, size=data_df.shape[0])
    data_df['with_jitter'] = data_df['Value'] + jitter

    index_further_away = None
    if add_anomalies:
        # As per the 68-95-99.7 rule(also known as the empirical rule) mu+-2*sd 
        # covers 95.4% of the dataset.
        # Since, anomalies are considered to be rare and typically within the 
        # 5-10% of the data; this filtering
        # technique might work 
        #for us(https://en.wikipedia.org/wiki/68%E2%80%9395%E2%80%9399.7_rule)
        indexes_furhter_away = np.where(np.abs(data_df['with_jitter']) > (mu + 
         2*sd))[0]
        logger.info(f"Number of points further away : 
        {len(indexes_furhter_away)}. Indexes: {indexes_furhter_away}")
        # Generate a point uniformly and embed it into the dataset
        random = rnd_state.uniform(0, 5, 1)
        data_df.loc[indexes_furhter_away, 'with_jitter'] +=  
        random*data_df.loc[indexes_furhter_away, 'with_jitter']
    return data_df, indexes_furhter_away

0

AWGN मतलाब समारोह के समान

def awgn(sinal):
    regsnr=54
    sigpower=sum([math.pow(abs(sinal[i]),2) for i in range(len(sinal))])
    sigpower=sigpower/len(sinal)
    noisepower=sigpower/(math.pow(10,regsnr/10))
    noise=math.sqrt(noisepower)*(np.random.uniform(-1,1,size=len(sinal)))
    return noise
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.