猿问

如何阻止 apply() 更改列的顺序?

我有一个可重现的例子,玩具数据框:


df = pd.DataFrame({'my_customers':['John','Foo'],'email':['email@gmail.com','othermail@yahoo.com'],'other_column':['yes','no']})


print(df)


  my_customers                email other_column

0         John      email@gmail.com          yes

1          Foo  othermail@yahoo.com           no

我apply()对行创建了一个函数,在函数内部创建了一个新列:


def func(row):


    # if this column is 'yes'

    if row['other_column'] == 'yes':


        # create a new column with 'Hello' in it        

        row['new_column'] = 'Hello' 


        # return to df

        return row 


    # otherwise

    else: 


        # just return the row

        return row

然后我将该函数应用于 df,我们可以看到顺序已更改。这些列现在按字母顺序排列。有没有办法避免这种情况?我想保持原来的顺序。


df = df.apply(func, axis = 1)

print(df)


                 email my_customers new_column other_column

0      email@gmail.com         John      Hello          yes

1  othermail@yahoo.com          Foo        NaN           no

为澄清而编辑 - 上面的代码太简单了


输入


df = pd.DataFrame({'my_customers':['John','Foo'],

                   'email':['email@gmail.com','othermail@yahoo.com'],

                   'api_status':['data found','no data found'],

                   'api_response':['huge json','huge json']})


  my_customers                email     api_status api_response

0         John      email@gmail.com     data found    huge json

1          Foo  othermail@yahoo.com  no data found    huge json

预期输出:


  my_customers                email     api_status api_response job_1 job_2  \

0         John      email@gmail.com     data found    huge json   xyz  xyz2   

1          Foo  othermail@yahoo.com  no data found    huge json   nan  nan


  education_1  facebook other api info  

0         foo  profile1            etc  

1         nan  nan                 nan


慕的地6264312
浏览 158回答 2
2回答

犯罪嫌疑人X

DataFrame运行应用功能后,您可以调整列的顺序。例如:df = df.apply(func, axis = 1)df = df[['my_customers', 'email', 'other_column', 'new_column']]为了减少重复的数量(即必须重新输入所有列名),您可以在调用 apply 函数之前获取现有的列集:columns = list(df.columns)df = df.apply(func, axis = 1)df = df[columns + ['new_column']]根据作者对原始问题的编辑进行更新。虽然我不确定选择的数据结构(将 API 结果存储在数据框中)是否是最佳选择,但一种简单的解决方案可能是在调用应用函数后提取新列。# Store the existing columns before calling applyexisting_columns = list(df.columns)df = df.apply(func, axis = 1)all_columns = list(df.columns)new_columns = [column for column in all_columns if column not in existing_columns]df = df[columns + new_columns]对于性能优化,您可以将现有列存储在 aset而不是 alist中,由于 Python 中集合数据结构的散列性质,这将在恒定时间内产生查找。这将更existing_columns = list(df.columns)改为existing_columns = set(df.columns).最后,正如@Parfait 在他们的评论中非常友好地指出的那样,上面的代码可能会引发一些折旧警告。使用pandas.DataFrame.reindex而不是df = df[columns + new_columns]将使警告消失:new_columns_order = [columns + new_columns]df = df.reindex(columns=new_columns_order)

汪汪一只猫

发生这种情况是因为您没有为新列分配值 if row["other_column"] != 'yes'。试试这个:def func(row):    if row['other_column'] == 'yes':        row['new_column'] = 'Hello'         return row     else:         row['new_column'] = ''         return rowdf.apply(func, axis = 1)您可以选择row["new_column"] == 'no'任何值。我只是把它留空。
随时随地看视频慕课网APP

相关分类

Python
我要回答