在函数中“就地”编辑数据框,或返回编辑后的数据框?

SCo*_*ool 5 python pandas

我目前正在开发一个更新数据框的功能。

我可以通过两种方式做到这一点。

示例 1:就地编辑。

创建数据框

mydf = pd.DataFrame({'name':['jim','john','mary','michael'],
                    'age':[12,46,44,32]})

      name  age
0      jim   12
1     john   46
2     mary   44
3  michael   32
Run Code Online (Sandbox Code Playgroud)

我们将进行以下编辑:

  1. 如果名称以 开头j,请添加'smith'到名称中。

  2. 如果年龄大于 40 岁,则乘以 2。

def modify(df):

    for i in range(len(df)):

        # if age is >40
        if df.loc[i,'age'] > 40:

            # multiply it by 2
            df.loc[i,'age'] = df.loc[i,'age']*2

        # get the name
        name = df.loc[i,'name']

        # if it starts with 'j'
        if name[0]=='j':

            # add 'smith' to the name
            name = name+' '+'smith'

        # insert into cell    
        df.loc[i,'name'] = name
Run Code Online (Sandbox Code Playgroud)

工作正常。我还没有从函数返回任何内容,并且数据框已被编辑:

modify(mydf)

print(mydf)

         name  age
0   jim smith   12
1  john smith   92
2        mary   88
3     michael   32
Run Code Online (Sandbox Code Playgroud)

示例 2我还可以通过返回数据帧来完成此操作,如下所示。我的问题是:有什么区别?一种方法优于另一种方法吗?

def modify(df):

    for i in range(len(df)):

        if df.loc[i,'age'] > 40:

            df.loc[i,'age'] = df.loc[i,'age']*2

        name = df.loc[i,'name']

        if name[0]=='j':

            name = name+' '+'smith'

        df.loc[i,'name'] = name

    return df
Run Code Online (Sandbox Code Playgroud)

运行该函数:

mydf = modify(mydf)

print(mydf)

         name  age
0   jim smith   12
1  john smith   92
2        mary   88
3     michael   32
Run Code Online (Sandbox Code Playgroud)

两者都工作正常。就地编辑好还是返回好dataframe

注意:我无法进行矢量化,因为我在正在处理的实际函数中使用 api。这只是一个玩具示例。

ALo*_*llz 4

我总是选择返回 DataFrame。如果您打算将输出分配给另一个变量 ( df1 = my_func(df)),请使用df.copy()或 确保您.copy()位于函数顶部,以免意外修改您的输入。

DataFrames是可变的,所以像列表一样,它们可以在函数内修改而不返回它们。pandas但是,当您使用返回新对象而不是修改原始对象的函数时,这可能会导致很多混乱。

mydf = pd.DataFrame({'name': ['jim', 'jim'],
                     'age': [12, 46]})

def modify(df):
    df.loc[df.name.eq('jim'), 'age'] = 1000

print(mydf)
#  name  age
#0  jim   12
#1  jim   46

modify(mydf)
print(mydf)
#  name   age
#0  jim  1000
#1  jim  1000
Run Code Online (Sandbox Code Playgroud)

好吧,太好了,情况发生了变化。但如果我们继续:

def modify2(df):
    df.drop_duplicates(inplace=True)
    df['age'] = df['age'] + 1

    df = pd.concat([df]*4)
    df['age'] = df['age'] + 17

modify2(mydf)
print(mydf)
#  name   age
#0  jim  1001
Run Code Online (Sandbox Code Playgroud)

所以这不太好。基本上,该函数仅成功修改df,直到函数的某些部分返回一个新对象而不是对原始对象的引用。这是非常有问题的,需要每个操作都就地操作,否则就会失败。