为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕的地6264312 2022-05-11 15:11:17
我有一个可重现的例子,玩具数据框:df = pd.DataFrame({'my_customers':['John','Foo'],'email':['email@gmail.com','othermail@yahoo.com'],'other_column':['yes','no']})print(df)  my_customers                email other_column0         John      email@gmail.com          yes1          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_column0      email@gmail.com         John      Hello          yes1  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_response0         John      email@gmail.com     data found    huge json1          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
查看完整描述

2 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

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 apply

existing_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)


查看完整回答
反对 回复 2022-05-11
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

发生这种情况是因为您没有为新列分配值 if row["other_column"] != 'yes'。试试这个:


def func(row):


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


        row['new_column'] = 'Hello' 

        return row 


    else: 


        row['new_column'] = '' 

        return row


df.apply(func, axis = 1)

您可以选择row["new_column"] == 'no'任何值。我只是把它留空。


查看完整回答
反对 回复 2022-05-11
  • 2 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信