目前,我正在学习如何编写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().Person
和Data.Person.male_only()
或为Data.male_only().data
和Data.data.male_only()
返回相同的答案,而不会永久性地更改Data.data
或Data.Person
。
我想详细说明@ Demi-Lune的答案。我认为没有办法可以绕开创建MyData
实例,对其进行修改并从链方法中将其返回。首先,这种事情起作用的全部原因是,您所有的链方法都属于同一类,并且它们返回该类的实例。
例如,str.swapcase
,str.zfill
和str.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.Person
或self.data["Person"]
?我对熊猫不是很熟悉。是字符串吗?字符串列表?无论如何,无论您要达到什么目的,基本上都需要将一个名为male_only
的新方法添加到该类型的类中。]
您在写self.data = ...
时在第一行中显式修改了self.data。您可以返回Data的新实例:
我同意@ Demi-Lune。