Pandas 数据帧浅拷贝对数据变化没有反应?
Pandas dataframe shallow copy not reacting to data changes?
我有一个包装器 class 来处理特定的数据框和一些修饰符 functions/callables 来处理它。
class PhoneNumberCleaner:
def __init__(self, data: pd.DataFrame, pattern: str):
self.data = data # shallow copy?
self.pattern = pattern
def __call__(self, *args, **kwargs) -> pd.DataFrame:
drop_mask = self.data['phoneNumber'].apply(
lambda pn: not re.fullmatch(self.pattern, pn)
)
drop_mask_index = drop_mask[drop_mask].index
return self.data.drop(drop_mask_index)
class Wrapper:
def __init__(self, data: pd.DataFrame):
self.data = data
def modify(self, modifier: Callable, *args, **kwargs):
self.data = modifier(*args, **kwargs)
现在,假设我有以下数据:
df_data = {
'name': ['Mickey', 'Anna', 'Todd', 'Lee', 'Amanda', 'Jake'],
'phoneNumber': [
'0321111444---',
'0335555666',
'0330001234',
'0330123456789',
'0328888999',
'0999999999999',
]
}
df = pd.DataFrame(df_data)
并且我想删除那些 phone 数字模式不正确的行:
wrapper = Wrapper(df)
number_cleaner = PhoneNumberCleaner(wrapper.data, r'\d{10}')
wrapper.modify(number_cleaner)
打印包装数据工作正常:
print(wrapper.data)
name phoneNumber
1 Anna 0335555666
2 Todd 0330001234
4 Amanda 0328888999
但是,当我想通过 PhoneNumberCleaner
对象访问相同的数据(应该指的是相同的数据帧)时,我得到了旧数据:
print(number_cleaner.data)
name phoneNumber
0 Mickey 0321111444---
1 Anna 0335555666
2 Todd 0330001234
3 Lee 0330123456789
4 Amanda 0328888999
5 Jake 0999999999999
我在Wrapper
和PhoneNumberCleaner
class中分配数据时尝试添加.copy(deep=False)
,但没有帮助。我在这里错过了什么?
这一行:
class PhoneNumberCleaner:
def __call__(self, *args, **kwargs) -> pd.DataFrame:
...
return self.data.drop(drop_mask_index)
DataFrame.drop
returns 一个新的数据框。原始数据框 (self.data
) 未被修改。
改为:
class PhoneNumberCleaner:
def __call__(self, *args, **kwargs) -> pd.DataFrame:
...
self.data.drop(drop_mask_index, inplace=True)
return self.data
我有一个包装器 class 来处理特定的数据框和一些修饰符 functions/callables 来处理它。
class PhoneNumberCleaner:
def __init__(self, data: pd.DataFrame, pattern: str):
self.data = data # shallow copy?
self.pattern = pattern
def __call__(self, *args, **kwargs) -> pd.DataFrame:
drop_mask = self.data['phoneNumber'].apply(
lambda pn: not re.fullmatch(self.pattern, pn)
)
drop_mask_index = drop_mask[drop_mask].index
return self.data.drop(drop_mask_index)
class Wrapper:
def __init__(self, data: pd.DataFrame):
self.data = data
def modify(self, modifier: Callable, *args, **kwargs):
self.data = modifier(*args, **kwargs)
现在,假设我有以下数据:
df_data = {
'name': ['Mickey', 'Anna', 'Todd', 'Lee', 'Amanda', 'Jake'],
'phoneNumber': [
'0321111444---',
'0335555666',
'0330001234',
'0330123456789',
'0328888999',
'0999999999999',
]
}
df = pd.DataFrame(df_data)
并且我想删除那些 phone 数字模式不正确的行:
wrapper = Wrapper(df)
number_cleaner = PhoneNumberCleaner(wrapper.data, r'\d{10}')
wrapper.modify(number_cleaner)
打印包装数据工作正常:
print(wrapper.data)
name phoneNumber
1 Anna 0335555666
2 Todd 0330001234
4 Amanda 0328888999
但是,当我想通过 PhoneNumberCleaner
对象访问相同的数据(应该指的是相同的数据帧)时,我得到了旧数据:
print(number_cleaner.data)
name phoneNumber
0 Mickey 0321111444---
1 Anna 0335555666
2 Todd 0330001234
3 Lee 0330123456789
4 Amanda 0328888999
5 Jake 0999999999999
我在Wrapper
和PhoneNumberCleaner
class中分配数据时尝试添加.copy(deep=False)
,但没有帮助。我在这里错过了什么?
这一行:
class PhoneNumberCleaner:
def __call__(self, *args, **kwargs) -> pd.DataFrame:
...
return self.data.drop(drop_mask_index)
DataFrame.drop
returns 一个新的数据框。原始数据框 (self.data
) 未被修改。
改为:
class PhoneNumberCleaner:
def __call__(self, *args, **kwargs) -> pd.DataFrame:
...
self.data.drop(drop_mask_index, inplace=True)
return self.data