无需永久更改对象的方法链接

问题描述 投票:0回答:3

目前,我正在学习如何编写python类和方法链接。基本上,我想要一个python(2.7)类来保留我的数据并具有(可链接的)方法,这些方法使我可以过滤数据而不会更改原始数据。我已经完成了一些谷歌搜索,似乎我的答案可能与return self有关,但是我不确定如何实现它,以使这些方法不会使我的原始数据发生变异。

假设我有一个存储在名为file的excel文件中的数据,如下所示:

+--------+-----+-------+
| Person | Sex | Score |
+--------+-----+-------+
| A      | M   |    10 |
| B      | F   |     9 |
| C      | M   |     8 |
| D      | F   |     7 |
+--------+-----+-------+

我想编写一个名为MyData的类,以便可以进行一些基本的数据调用和过滤。

这是我到目前为止所得到的

class MyData:
    def __init__ (self, file):
        import pandas as pd
        self.data = pd.read_excel (file)
        self.Person = self.data['Person']
        self.Sex = self.data['Sex']
        self.Score = self.data['Score']

    def male_only(self):
        self.data = self.data[self.Sex=="M"]
        self.Person = self.Person[self.Sex=="M"]
        self.Score = self.Score[self.Sex=="M"]
        self.Sex = self.Sex[self.Sex=="M"]
        return self

    def female_only(self):
        self.data = self.data[self.Sex=="F"]
        self.Person = self.Person[self.Sex=="F"]
        self.Score = self.Score[self.Sex=="F"]
        self.Sex = self.Sex[self.Sex=="F"]
        return self

这似乎可行,但是很遗憾,我的原始数据被此代码永久性地突变了。例如:

Data = MyData(file)
Data.data
>>> Data.data
  Person Sex  Score
0      A   M     10
1      B   F      9
2      C   M      8
3      D   F      7

Data.male_only().data
>>> Data.male_only().data
  Person Sex  Score
0      A   M     10
2      C   M      8

Data.data
>>> Data.data
  Person Sex  Score
0      A   M     10
2      C   M      8

我希望一个类为Data.male_only().PersonData.Person.male_only()或为Data.male_only().dataData.data.male_only()返回相同的答案,而不会永久性地更改Data.dataData.Person

python pandas python-2.x method-chaining
3个回答
0
投票

我想详细说明@ Demi-Lune的答案。我认为没有办法可以绕开创建MyData实例,对其进行修改并从链方法中将其返回。首先,这种事情起作用的全部原因是,您所有的链方法都属于同一类,并且它们返回该类的实例。

例如,str.swapcasestr.zfillstr.replace都是str的一部分,它们都返回str

>>> string = "Hello World"
>>> string.swapcase().zfill(16).replace("L", "T")
'00000hETTO wORTD'
>>> string
'Hello World'
>>> 

您要尝试执行的操作(Data.Person.male_only())打破了这种模式,因为现在隐含了方法male_only不是MyData类的一部分,而是属于Person的方法宾语。什么是self.Personself.data["Person"]?我对熊猫不是很熟悉。是字符串吗?字符串列表?无论如何,无论您要达到什么目的,基本上都需要将一个名为male_only的新方法添加到该类型的类中。]


0
投票

您在写self.data = ...时在第一行中显式修改了self.data。您可以返回Data的新实例:


0
投票

我同意@ Demi-Lune。

© www.soinside.com 2019 - 2024. All rights reserved.