【问题标题】:Manipulating DataFrame with custom dataclass methods使用自定义数据类方法操作 DataFrame
【发布时间】:2022-01-22 02:50:28
【问题描述】:

我有超过 4000 行代码用于分析、操作、比较和绘制 2 个巨大的 .csv 文档。为了可读性和将来的发布,我想转换为面向对象的类。我将它们转换为pd.DataFrames

my_data1 = pd.DataFrame(np.random.randn(100, 9), columns=list('123456789'))
my_data2 = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

我有比较每个数据集的各个方面的函数和只单独使用数据集的函数。我想将此结构转换为具有每个数据帧的方法的数据类。

我无法通过我的类函数操作这些数据帧。我不断收到NameError: name 'self' is not defined。这是我的数据类结构:

@dataclass
class Data:
    ser = pd.DataFrame 

    # def __post_init__(self):
    #     self.ser = self.clean()

    def clean(self, ser):
        acceptcols = np.where(ser.loc[0, :] == '2')[0]
        data = ser.iloc[:, np.insert(acceptcols, 0, 0)]
        data = ser.drop(0)
        data = ser.rename(columns={'': 'Time(s)'})
        data = ser.astype(float)
        data = ser.reset_index(drop=True)
        data.columns = [column.replace('1', '')
                        for column in ser.columns]

        return data


my_data1 = pd.DataFrame(np.random.randn(100, 9), columns=list('123456789'))
my_data2 = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

# Attempt 1
new_data1 = Data.clean(my_data1) # Parameter "ser" unfilled 
# Attempt 2
new_data1 = Data.clean(ser=my_data1) # Parameter "self" unfilled 
# Attempt 3
new_data1 = Data.clean(self, my_data1) # Unresolved reference "self"

我尝试过各种形式的定义def clean(self and other stuff),但我认为我对类或类结构还不够了解。关于类和数据类的文档总是使用非常基本的示例,我尝试剪切/粘贴模板无济于事。我错过了什么?

【问题讨论】:

    标签: python pandas dataframe class python-dataclasses


    【解决方案1】:

    你可以先获取Data类的实例x

    x = Data()
    
    # Attempt 1
    new_data1 = x.clean(my_data1) # Parameter "ser" unfilled 
    # Attempt 2
    new_data1 = x.clean(ser=my_data1) # Parameter "self" unfilled 
    

    如果我是你,我不会以这种方式使用类,而是只定义以下函数

    def clean(ser):
            acceptcols = np.where(ser.loc[0, :] == '2')[0]
            data = ser.iloc[:, np.insert(acceptcols, 0, 0)]
            data = ser.drop(0)
            data = ser.rename(columns={'': 'Time(s)'})
            data = ser.astype(float)
            data = ser.reset_index(drop=True)
            data.columns = [column.replace('1', '')
                            for column in ser.columns]
    
            return data
    

    并直接调用它。

    另外,在您的clean() 中,每次修改都基于ser,这是输入,但不是最后一次修改。这是个问题,不是吗?

    【讨论】:

    • 最后的修改是(或应该是)对输入的修改,ser,它的目标是用一个空字符串替换每列“1”。起初,它只是一个像上面包含的函数,但数据集变得非常复杂,我想在类中测试函数以尝试使所有内容更具可读性。为什么你认为我不应该使用这样的类?
    • #1 即使您只是定义了一个函数clean,您也可以根据需要多次调用它,这样代码仍然可读。只有当一个类表示一个具有许多方法和许多属性的对象时,它才会更好。在你的情况下,一个函数就足够了。
    • #2 您在clean 中有 6 处修改,但只有最后 2 处会出现在您的最终结果中。如果您想恢复所有修改,请将所有 ser 更改为 data 第一个和第二个除外。
    • 如果我是你,我仍然不会使用课程。一个类代表一个对象,在你的情况下,你只想对你的函数进行分组,所以这就是区别。我会选择以下两种方式之一。 #1 将所有函数定义为函数,并在需要的地方调用它们。 #2 将特定于 my_data1 的函数放在一个 .py 文件中;和 my_data2 一样;最后将共享函数放入第三个 .py 文件中。
    • 最后我可以为 my_data1 定义一个封装函数,调用所有 20 个函数,为 my_data2 定义一个封装函数,调用所有 15 个函数。
    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 2017-02-04
    • 2013-03-31
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多