【问题标题】:Add new column based on multiple column values using apply [duplicate]使用应用添加基于多个列值的新列 [重复]
【发布时间】:2019-07-18 14:38:17
【问题描述】:

我想向 test_df 添加一个新列,其中包含列 a 或 b 的值,具体取决于 change_col 以及 change 是否为 True。下面的 for 循环可以工作,但是太慢了。 如何使用 apply 或类似方法添加新列?

test_df = pd.DataFrame({"a":[1,1,2,3],
                    "b":["ant","ber","cas","dor"],
                    "change_col":["a","b","b","a"],
                    "change":[True,True,True,False]})

    a   b      change_col   change
0   1   ant        a       True
1   1   ber        b       True
2   2   cas        b       True
3   3   dor        a       False

所需的df:

    a   b     change_col    change  new_value
0   1   ant        a        True    1
1   1   ber        b        True    ber
2   2   cas        b        True    cas
3   3   dor        a        False   NaN

我的for循环

new_value= []
for _ , row in test_df.iterrows():
    if row["change"] is True:
        new_value +=[row[row["change_column"]]]
    else:
        new_value += [np.NaN]
test_df["new_value"] = new_value

我在 python 3.7 上使用 pandas 0.24.2。

【问题讨论】:

  • 不同意重复,这不是简单的查找。在 Vaishali 的回答下查看我的评论

标签: python-3.x pandas


【解决方案1】:

你可以使用[DataFrame.lookup][1],

test_df['new_val'] = test_df.lookup(test_df.index, test_df['change_col'])

    a   b   change_col  change  new_val
0   1   ant a           True    1
1   1   ber b           True    ber
2   2   cas b           True    cas
3   3   dor a           False   3

编辑:要考虑更改列,请使用条件

test_df['new_val'] = np.where(test_df['change'], test_df.lookup(test_df.index, test_df['change_col']), np.nan)

    a   b   change_col  change  new_val
0   1   ant a           True    1
1   1   ber b           True    ber
2   2   cas b           True    cas
3   3   dor a           False   NaN

【讨论】:

  • 像这个一样,你只是错过了一个条件,这应该可以工作:np.where(test_df['change'], test_df.lookup(test_df.index, test_df['change_col']), np.NaN)
  • @Erfan,是的,我没有看到更改条件,谢谢
  • 也适用于多列!
【解决方案2】:

由于您有多个条件,我们可以在此处使用np.select 来定义我们的条件,并根据这些条件选择我们的值:

conditions = [
    test_df['change_col'].eq('a') & test_df['change'].eq(True),
    test_df['change_col'].eq('b') & test_df['change'].eq(True)
]

test_df['new_value'] = np.select(conditions, choicelist=[test_df['a'], test_df['b']], default=np.NaN)

输出

   a    b change_col  change new_value
0  1  ant          a    True         1
1  1  ber          b    True       ber
2  2  cas          b    True       cas
3  3  dor          a   False       NaN

【讨论】:

  • 选择有默认值,很好:D
  • 是的:),另外我喜欢明确地编程eq(True),因为它可能会让初学者混淆理解它与矢量化解决方案(如np.select@Adam.Er8)结合使用@Adam.Er8
【解决方案3】:

这是一个使用np.select的解决方案:

import pandas as pd
import numpy as np

test_df = pd.DataFrame({"a": [1, 1, 2, 3],
                        "b": ["ant", "ber", "cas", "dor"],
                        "change_col": ["a", "b", "b", "a"],
                        "change": [True, True, True, False]})

change_a = ((test_df['change']) & (test_df['change_col'] == 'a'))
change_b = ((test_df['change']) & (test_df['change_col'] == 'b'))
dont_change = ~test_df['change']

conditions = [change_a, change_b, dont_change]
choices = [test_df['a'], test_df['b'], np.nan]

test_df["new_value"] = np.select(conditions, choices)

print(test_df)

输出:

   a    b  change change_col new_value
0  1  ant    True          a         1
1  1  ber    True          b       ber
2  2  cas    True          b       cas
3  3  dor   False          a       NaN

【讨论】:

    猜你喜欢
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 2022-08-11
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多