【问题标题】:Input object of function will be overwritten by return函数的输入对象会被return覆盖
【发布时间】:2018-06-01 22:47:34
【问题描述】:

我对 Python 比较陌生,但我遇到了一个函数问题。基本上,这个函数应该编辑一个 pandas 数据框并以一个新的对象名称返回它。所以保持原来的对象不变。返回的对象应保存在新对象中。我的问题是,输入对象也会受到影响。即使我将结果保存到新对象,如何防止我的输入对象受到该函数的影响。我读过一些关于不可变和可变对象的文章,但是如何更改我的函数。

import pandas as pd
import numpy as np

msg_items = pd.DataFrame({'Column_A': [10,20,30,40,50,60]})

print('Before: ', msg_items.dtypes)

def justdoit(myframe):
    cols = list(myframe)
    myframe[cols] = myframe[cols].applymap(np.str)
    return myframe

testframe = justdoit(msg_items)

print('After: ', msg_items.dtypes)

实际输出:

Before:  Column_A    int64
dtype: object
After:  Column_A    object
dtype: object

预期输出:

Before:  Column_A    int64
dtype: object
After:  Column_A    int64
dtype: object

【问题讨论】:

  • myframe[cols] = myframe[cols].applymap(np.str) 编辑原始数据框,它不会创建新数据框。
  • 我怎样才能创建一个新的,而不是编辑原始数据框?
  • 不要用applymap,用copy新建一个(看我的回答)

标签: python function pandas return


【解决方案1】:

如果您的目标是在不修改原始数据的情况下将数据帧转换为字符串,那么您做的不对,因为

myframe[cols] = myframe[cols].applymap(np.str)
  1. 将结果分配回原始数据帧,因此就地进行更改
  2. 不是将列转换为字符串的最流行的方式

进一步,

return myframe

返回 same 对象,您只是将其分配给 新变量。只有一个数据框,但有两种访问方式,通过两个变量!

要将数据框转换为字符串,请使用astype(str) -

def just_do_it(df):
    return df.astype(str)

如果要编辑子集并返回副本,请致电df.copy -

def just_do_it(df, subset):
    df_new = df.copy()
    df_new[subset] = df_new[subset].astype(str)

    return df_new

new_msg_items = just_do_it(msg_items, subset=list(msg_items))
msg_items.dtypes
Column_A    int64
dtype: object

new_msg_items.dtypes
Column_A    object
dtype: object

附带说明,如果您有可变类型的列,您可能需要执行 deepcopy。在这种情况下,使用deep=True 调用copy -

df_new = df.copy(deep=True)

【讨论】:

  • 感谢您的解释!你们真棒。没想到这么复杂的案子。我来自 R,我倾向于只使用箭头来复制对象。
  • @ErikSteiner 干杯,对于所有使用 python 的人来说,这是一个常见的问题。
【解决方案2】:

在您的函数中 - 使用 copy.deepcopy(x) 创建一个新对象,然后更改其上的值并返回它。

def justdoit(myframe):
    cols = list(myframe)
    myframe_new = copy.deepcopy(myframe)
    myframe_new [cols] = myframe[cols].applymap(np.str)
    return myframe_new 

【讨论】:

  • 与其他答案相同,applymap 不是用于字符串转换的好方法。事实上,你甚至可以使用copy.deepcopy,而你可以只使用df.copy
猜你喜欢
  • 2012-01-11
  • 2013-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2019-09-21
  • 2017-06-24
  • 2020-02-29
相关资源
最近更新 更多