在使用Pandas的Python中,我有一个函数来更改DataFrame的索引。但是,它也会更改原始数据帧的索引

在使用Pandas的Python中,我有一个函数来更改DataFrame的索引。但是,它也会更改原始数据帧的索引,python,pandas,function,datetimeindex,Python,Pandas,Function,Datetimeindex,我有以下analysis.py文件。功能group\u analysis通过df\u input的Count列更改df\u input的日期时间索引 #analysis.py 作为pd进口熊猫 def组分析(df组输入): df_input.index=df_input.index-pd.to_timedelta(df_input.Count,单位为“天”) df_output=df_input.sort_index() 返回数据输出 def测试(df): df=df+1 返回df 我有一个如

我有以下
analysis.py
文件。功能
group\u analysis
通过
df\u input
Count
列更改
df\u input
的日期时间索引

#analysis.py
作为pd进口熊猫
def组分析(df组输入):
df_input.index=df_input.index-pd.to_timedelta(df_input.Count,单位为“天”)
df_output=df_input.sort_index()
返回数据输出
def测试(df):
df=df+1
返回df
我有一个如下的数据帧

x=pd.DataFrame(np.arange(1,14),index=pd.date\u范围('2020-01-01',句点=13,频率=D'),列=['Count']
当我运行以下代码时

导入分析
y=分析。组分析(x)
x和y的日期时间索引都已更改(因此,
x.equals(y)
True
)。为什么
group\u analysis
同时更改输入和输出日期时间索引?我怎样才能只更改
y
(而不是
x
)的日期时间索引

但是,当运行以下代码时,
x
不会改变(因此,
x.equals(y)
True


编辑:添加了analysis.test(df)。

此行为的原因是,在调用
group_analysis
时,您没有将数据帧的副本传递给函数,而是传递了对计算机内存中原始数据的引用。因此,如果修改其后面的数据,原始数据(相同)也将被修改

有关非常好的解释,请参阅

要防止出现这种情况,请在输入函数时创建数据副本:

...
def group_analysis(df):
    df_input = df.copy()
    ...

当您将数据帧传递给函数时,它将传递数据帧引用。因此,对数据帧所做的任何就地更改都将反映在传递的数据帧中

但是对于
test
函数,加法返回内存中数据帧的副本。我怎么知道?只需在操作前后打印变量的内存引用id

>>> def test(df):
...     print(id(df))
...     df = df + 1
...     print(id(df))
...     return df
... 
>>> test(df)
139994174011920
139993943207568

注意到变化了吗?这意味着其引用已更改。因此不会影响原始数据帧。

尝试
y=analysis.group\u analysis(x.copy())
?这是因为您正在将原始数据帧的引用传递给函数@大卫78谢谢你的帮助:)。当另一个函数只更改x的值,而不更改x的datetime索引时,我没有这个问题。例如,def test():df=df+1返回df。是否只有当函数更改数据帧的索引时才会出现问题?文件的第一行指定给作为输入数据帧属性的索引。因此不会创建数据帧本身的副本。进行添加时,它会在添加后返回数据帧的副本。为了演示这一点,请尝试使用一个dataframe函数,将inplace参数设置为true。你会注意到变化的@大卫78谢谢你的帮助。请找到编辑过的原始帖子,在那里我添加了一个新功能“测试(df)”。我不清楚为什么在“测试(df)”中找不到该问题。感谢您的帮助:)。当另一个函数只更改x的值,而不更改x的datetime索引时,我没有这个问题。例如,def test():df=df+1返回df。是否只有当函数改变数据帧的索引时才会出现问题?我相信这取决于变量的类型。使用简单类型时,不会修改调用变量。虽然不确定您的示例是什么,但是
df
应该是测试的参数吗?谢谢您的帮助。请找到编辑过的原始帖子,在那里我添加了一个新功能“测试(df)”。我不清楚为什么在“测试(df)”中找不到该问题。感谢您的澄清!!。但我不知道如何找出哪个返回数据帧副本,哪个不返回。有没有具体的规定?“group_analysis(df_input)”的第一行将“pd.减去_timedelta(df_input.Count,unit='days'),但它不返回副本。您为什么想知道这一点?Python总是作为引用传递到函数中。除非您希望更改原始数据帧,否则将传递一个副本。每个函数的行为都不同。正如我所说,你需要考虑一下推荐人。谢谢你的帮助。我有许多以数据帧作为输入的函数。因为我过去从未考虑过这个问题,所以我的其他函数都是在没有考虑它的情况下生成的。因此,我想知道函数在什么情况下不返回副本来查看其他函数。再次感谢。我们也有很多基于数据帧转换的函数。但我们在流程开始时复制了一份。
...
def group_analysis(df):
    df_input = df.copy()
    ...
>>> def test(df):
...     print(id(df))
...     df = df + 1
...     print(id(df))
...     return df
... 
>>> test(df)
139994174011920
139993943207568