Pandas Class 与 Pandas .pipe()
Pandas Class with Pandas .pipe()
@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:
def __init__(self, pandas_obj):
self._obj = pandas_obj
def multiply(self, col):
self._obj[col] = self._obj[col] * self._obj[col]
return self._obj
def square(self, col):
self._obj[col] = self._obj[col]**2
return self._obj
def add_strings(self, col):
self._obj[col] = self._obj[col] + self._obj[col]
return self._obj
def process_all(self):
self._obj.pipe(
self.multiply(col='A'),
self.square(col='B')
self.add_strings(col='C')
)
class DataProcessor(DataCleaner):
data = [
[1, 1.5, "AABB"],
[2, 2.5, "BBCC"],
[3, 3.5, "CCDD"],
[4, 4.5, "DDEE"],
[5, 5.5, "EEFF"],
[6, 6.5, "FFGG"],
]
def __init__(self):
self.df = pd.DataFrame(data=DataProcessor.data, columns=['A', 'B', 'C'])
def get_data(self):
return self.df
def clean_the_df(self, obj):
obj = obj.data_cleaner.multiply(col='A')
obj = obj.data_cleaner.square(col='B')
obj = obj.data_cleaner.add_strings(col='C')
return obj
def process_all(self, obj):
obj = obj.data_cleaner.process_all()
if __name__ == '__main__':
data = DataProcessor().get_data()
# this works
print(DataProcessor().clean_the_df(data))
# this does not work
print(DataProcessor().process_all(data))
我想将 pandas .pipe()
函数与数据框访问器一起使用,以将方法链接在一起。在 DataCleaner
class 中,我有一个方法 process_all
,其中包含 class 中的其他清洁方法。我想将它们链接在一起并一次性使用多种方法处理数据帧。
最好将此链接方法保留在 DataCleaner
class 中,因此我所要做的就是从另一个 Class 或文件中调用一次,例如process_all
里面 DataProcessor
.
这样我就不必单独写出每个方法来一次处理一个数据帧,例如 DataProcessor.clean_the_df()
。
问题是 process_all
正在抱怨:TypeError: 'DataFrame' object is not callable
所以我的问题是,如何使用 pandas 数据帧访问器 self.obj
和 .pipe()
将多个清理方法链接到一个函数中,以便我可以调用它来自另一个 class 的函数并一次性使用多种方法处理数据帧?
process_all
的期望输出:
A B C
0 1 2.25 AABBAABB
1 4 6.25 BBCCBBCC
2 9 12.25 CCDDCCDD
3 16 20.25 DDEEDDEE
4 25 30.25 EEFFEEFF
5 36 42.25 FFGGFFGG
这里的问题是 .pipe
需要一个接受 DataFrame、Series 或 GroupBy 对象的函数。文档对此非常清楚:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pipe.html。最重要的是,DataCleaner.process_all
函数没有正确实现 .pipe
。为了链接几个函数,预期的语法是:
>>>(df.pipe(h)
... .pipe(g, arg1=a)
... .pipe(func, arg2=b, arg3=c)
... )
相当于
>>>func(g(h(df), arg1=a), arg2=b, arg3=c)
为了将数据框访问器与 .pipe
相结合,您需要在 DataCleaner
class 中定义静态方法,将 DataFrame 和列作为参数。这是解决您的问题的示例:
@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:
def __init__(self, pandas_obj):
self._obj = pandas_obj
@staticmethod
def multiply(df, col):
df[col] = df[col] * df[col]
return df
@staticmethod
def square(df, col):
df[col] = df[col]**2
return df
@staticmethod
def add_strings(df, col):
df[col] = df[col] + df[col]
return df
def process_all(self):
self._obj = (self._obj.pipe(self.multiply, col='A')
.pipe(self.square, col='B')
.pipe(self.add_strings, col='C'))
return self._obj
class DataProcessor(DataCleaner):
data = [
[1, 1.5, "AABB"],
[2, 2.5, "BBCC"],
[3, 3.5, "CCDD"],
[4, 4.5, "DDEE"],
[5, 5.5, "EEFF"],
[6, 6.5, "FFGG"],
]
def __init__(self):
self.df = pd.DataFrame(data=DataProcessor.data, columns=['A', 'B', 'C'])
def get_data(self):
return self.df
def clean_the_df(self, obj):
obj = obj.data_cleaner.multiply(obj, col='A') # modified to use static method
obj = obj.data_cleaner.square(obj, col='B')
obj = obj.data_cleaner.add_strings(obj, col='C')
return obj
def process_all(self, obj):
obj = obj.data_cleaner.process_all()
return obj
使用此代码,运行 这应该产生:
>>>data = data = DataProcessor().get_data()
>>>print(DataProcessor().process_all(data))
A B C
0 1 2.25 AABBAABB
1 4 6.25 BBCCBBCC
2 9 12.25 CCDDCCDD
3 16 20.25 DDEEDDEE
4 25 30.25 EEFFEEFF
5 36 42.25 FFGGFFGG
@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:
def __init__(self, pandas_obj):
self._obj = pandas_obj
def multiply(self, col):
self._obj[col] = self._obj[col] * self._obj[col]
return self._obj
def square(self, col):
self._obj[col] = self._obj[col]**2
return self._obj
def add_strings(self, col):
self._obj[col] = self._obj[col] + self._obj[col]
return self._obj
def process_all(self):
self._obj.pipe(
self.multiply(col='A'),
self.square(col='B')
self.add_strings(col='C')
)
class DataProcessor(DataCleaner):
data = [
[1, 1.5, "AABB"],
[2, 2.5, "BBCC"],
[3, 3.5, "CCDD"],
[4, 4.5, "DDEE"],
[5, 5.5, "EEFF"],
[6, 6.5, "FFGG"],
]
def __init__(self):
self.df = pd.DataFrame(data=DataProcessor.data, columns=['A', 'B', 'C'])
def get_data(self):
return self.df
def clean_the_df(self, obj):
obj = obj.data_cleaner.multiply(col='A')
obj = obj.data_cleaner.square(col='B')
obj = obj.data_cleaner.add_strings(col='C')
return obj
def process_all(self, obj):
obj = obj.data_cleaner.process_all()
if __name__ == '__main__':
data = DataProcessor().get_data()
# this works
print(DataProcessor().clean_the_df(data))
# this does not work
print(DataProcessor().process_all(data))
我想将 pandas .pipe()
函数与数据框访问器一起使用,以将方法链接在一起。在 DataCleaner
class 中,我有一个方法 process_all
,其中包含 class 中的其他清洁方法。我想将它们链接在一起并一次性使用多种方法处理数据帧。
最好将此链接方法保留在 DataCleaner
class 中,因此我所要做的就是从另一个 Class 或文件中调用一次,例如process_all
里面 DataProcessor
.
这样我就不必单独写出每个方法来一次处理一个数据帧,例如 DataProcessor.clean_the_df()
。
问题是 process_all
正在抱怨:TypeError: 'DataFrame' object is not callable
所以我的问题是,如何使用 pandas 数据帧访问器 self.obj
和 .pipe()
将多个清理方法链接到一个函数中,以便我可以调用它来自另一个 class 的函数并一次性使用多种方法处理数据帧?
process_all
的期望输出:
A B C
0 1 2.25 AABBAABB
1 4 6.25 BBCCBBCC
2 9 12.25 CCDDCCDD
3 16 20.25 DDEEDDEE
4 25 30.25 EEFFEEFF
5 36 42.25 FFGGFFGG
这里的问题是 .pipe
需要一个接受 DataFrame、Series 或 GroupBy 对象的函数。文档对此非常清楚:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pipe.html。最重要的是,DataCleaner.process_all
函数没有正确实现 .pipe
。为了链接几个函数,预期的语法是:
>>>(df.pipe(h)
... .pipe(g, arg1=a)
... .pipe(func, arg2=b, arg3=c)
... )
相当于
>>>func(g(h(df), arg1=a), arg2=b, arg3=c)
为了将数据框访问器与 .pipe
相结合,您需要在 DataCleaner
class 中定义静态方法,将 DataFrame 和列作为参数。这是解决您的问题的示例:
@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:
def __init__(self, pandas_obj):
self._obj = pandas_obj
@staticmethod
def multiply(df, col):
df[col] = df[col] * df[col]
return df
@staticmethod
def square(df, col):
df[col] = df[col]**2
return df
@staticmethod
def add_strings(df, col):
df[col] = df[col] + df[col]
return df
def process_all(self):
self._obj = (self._obj.pipe(self.multiply, col='A')
.pipe(self.square, col='B')
.pipe(self.add_strings, col='C'))
return self._obj
class DataProcessor(DataCleaner):
data = [
[1, 1.5, "AABB"],
[2, 2.5, "BBCC"],
[3, 3.5, "CCDD"],
[4, 4.5, "DDEE"],
[5, 5.5, "EEFF"],
[6, 6.5, "FFGG"],
]
def __init__(self):
self.df = pd.DataFrame(data=DataProcessor.data, columns=['A', 'B', 'C'])
def get_data(self):
return self.df
def clean_the_df(self, obj):
obj = obj.data_cleaner.multiply(obj, col='A') # modified to use static method
obj = obj.data_cleaner.square(obj, col='B')
obj = obj.data_cleaner.add_strings(obj, col='C')
return obj
def process_all(self, obj):
obj = obj.data_cleaner.process_all()
return obj
使用此代码,运行 这应该产生:
>>>data = data = DataProcessor().get_data()
>>>print(DataProcessor().process_all(data))
A B C
0 1 2.25 AABBAABB
1 4 6.25 BBCCBBCC
2 9 12.25 CCDDCCDD
3 16 20.25 DDEEDDEE
4 25 30.25 EEFFEEFF
5 36 42.25 FFGGFFGG