将方法传递给另一个函数的 Pythonic 方式

发布于 2025-01-14 15:57:12 字数 2632 浏览 3 评论 0原文

我不确定执行以下操作的最佳方法。也就是说,我不确定是否应该有一个父类 UniSamplingStrategy 和子类 UniformSampling 和 RandomSampling。或者我应该只拥有 UniSamplingStrategy 并将采样类型作为方法?例如,这就是我所做的:

import numpy as np

## make a base class w/ child classes instead?
class UniSamplingStrategy():
    def __init__(self, 
                 left=0, 
                 right=0,
                 num_samples=0, 
                 cluster_center=None, 
                 defined_array=[0]
                ):
    
        self._left = left
        self._right = right
        self._num_samples = num_samples
        self._cluster_center = cluster_center
        self._defined_array = defined_array

   # uniform sampling
   def uniform_sampling(self):
        return np.linspace(start=self._left, 
                           stop=self._right, 
                           num=self._num_samples, 
                           endpoint=True, 
                           dtype=np.float32)

   # random spacing
   def clustered_sampling(self):
        return np.random.normal(loc=self._clust_center, 
                                scale=(self._right - self._left)/4, 
                                size=self._num_samples)

我想要对这个类(或者可能是类,如果我需要重写以获得良好的 python)做的是将采样策略传递给我的 data_ Generation 方法。

def data_generation(noise_scale, 
                    sampling_strategy, 
                    test_func,
                    noise_type
                   ):

    x_samples = sampling_strategy
    y_samples = test_func(x=x_samples)


    if noise_type is not None:
        _, y_samples_noise = noise_type(x=x_samples, scale=noise_scale)
        y_samples = y_samples + y_samples_noise

    return x_samples, y_samples

def test_func(x): 
    return (np.cos(x))**2/((x/6)**2+1)

def hmskd_noise(x, scale):  
    scales = scale
    return scales, np.random.normal(scale=scale, size=x.shape[0])

因此,理想情况下,我可以尝试不同的测试函数、噪声和采样方案。我可以在其中编写如下函数调用:

x_true, y_true = data_generation(sampling_strategy=uniform_sampling(left=0, right=10, num_samples=1000)
                                 test_func = test_func,
                                 noise_type=None,
                                 noise_scale = 0)

x_obs, y_obs = data_generation(sampling_strategy=clustered_sampling(clustered_center=5, left=0, right=10, num_samples = 20),
                               test_func = test_func,
                               noise_type=hmskd_noise,
                               noise_scale=0.2)

本质上,我感兴趣的是当每个方法可以有不同的参数传递时,将采样策略传递给 data_ Generation 的最佳方式(例如,请参阅uniform_sampling 和 clustered_sampling 参数)。

感谢您的宝贵时间:)

I'm unsure the best way to do the following. That is, I'm not sure if I should have a parent class UniSamplingStrategy and child classes UniformSampling, and RandomSampling. Or should I just have UniSamplingStrategy and have the types of samplings as methods? For example, this is what I did:

import numpy as np

## make a base class w/ child classes instead?
class UniSamplingStrategy():
    def __init__(self, 
                 left=0, 
                 right=0,
                 num_samples=0, 
                 cluster_center=None, 
                 defined_array=[0]
                ):
    
        self._left = left
        self._right = right
        self._num_samples = num_samples
        self._cluster_center = cluster_center
        self._defined_array = defined_array

   # uniform sampling
   def uniform_sampling(self):
        return np.linspace(start=self._left, 
                           stop=self._right, 
                           num=self._num_samples, 
                           endpoint=True, 
                           dtype=np.float32)

   # random spacing
   def clustered_sampling(self):
        return np.random.normal(loc=self._clust_center, 
                                scale=(self._right - self._left)/4, 
                                size=self._num_samples)

What I want to do with this class (or perhaps classes, if I need to rewrite for good python) is pass a sampling strategy to my data_generation method.

def data_generation(noise_scale, 
                    sampling_strategy, 
                    test_func,
                    noise_type
                   ):

    x_samples = sampling_strategy
    y_samples = test_func(x=x_samples)


    if noise_type is not None:
        _, y_samples_noise = noise_type(x=x_samples, scale=noise_scale)
        y_samples = y_samples + y_samples_noise

    return x_samples, y_samples

def test_func(x): 
    return (np.cos(x))**2/((x/6)**2+1)

def hmskd_noise(x, scale):  
    scales = scale
    return scales, np.random.normal(scale=scale, size=x.shape[0])

So that ideally, I could try different test functions, noise, and sampling schemes. Where I could write function calls like:

x_true, y_true = data_generation(sampling_strategy=uniform_sampling(left=0, right=10, num_samples=1000)
                                 test_func = test_func,
                                 noise_type=None,
                                 noise_scale = 0)

x_obs, y_obs = data_generation(sampling_strategy=clustered_sampling(clustered_center=5, left=0, right=10, num_samples = 20),
                               test_func = test_func,
                               noise_type=hmskd_noise,
                               noise_scale=0.2)

Essentially, I'm interested in the best way to pass a sampling strategy to data_generation when each method can have different parameters to pass (e.g., see uniform_sampling and clustered_sampling parameters).

Thanks for your time :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁〃客ぐ 2025-01-21 15:57:12

例如,您可以拥有一组带有 __call__ 方法的类。就像

class UniformSampling:
    def __init__(self, 
                 left=0, 
                 right=0,
                 num_samples=0, 
                 cluster_center=None, 
                 defined_array=[0]
                ):
    
        self._left = left
        self._right = right
        self._num_samples = num_samples
        self._cluster_center = cluster_center
        self._defined_array = defined_array

    def __call__(self, arg1, arg2):
        return np.linspace(start=self._left, 
                            stop=self._right, 
                            num=self._num_samples, 
                            endpoint=True, 
                            dtype=np.float32)

那么你可以将实例化对象传递给 data_ Generation 作为

x_true, y_true = data_generation(sampling_strategy=UniformSampling(left=0, right=10, num_samples=1000),
                                 test_func = test_func,
                                 noise_type=None,
                                 noise_scale = 0)

For example, you can have a set of classes with __call__ method. Like

class UniformSampling:
    def __init__(self, 
                 left=0, 
                 right=0,
                 num_samples=0, 
                 cluster_center=None, 
                 defined_array=[0]
                ):
    
        self._left = left
        self._right = right
        self._num_samples = num_samples
        self._cluster_center = cluster_center
        self._defined_array = defined_array

    def __call__(self, arg1, arg2):
        return np.linspace(start=self._left, 
                            stop=self._right, 
                            num=self._num_samples, 
                            endpoint=True, 
                            dtype=np.float32)

Then you can pass instantiated object to data_generation as

x_true, y_true = data_generation(sampling_strategy=UniformSampling(left=0, right=10, num_samples=1000),
                                 test_func = test_func,
                                 noise_type=None,
                                 noise_scale = 0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文