【问题标题】:how to return return values based on another columns values in pandas?如何根据熊猫中的另一列值返回返回值?
【发布时间】:2020-12-07 12:02:32
【问题描述】:

我有 DF:

  col1|  col2|
   "a"| "stg"|
   "b"| "etc"|
   "a"| "xyz"|
   "b"| "wha"|

我需要下一个输出:

  col1|  col2|   col3|
   "a"| "stg"|"stg:1"|
   "b"| "etc"|"etc:2"|
   "a"| "xyz"|"xyz:1"|
   "b"| "wha"|"wha:2"|

所以基本上我有两列只有字符串作为变量我需要的是第三列,它检查 col1。如果它是一个 'a' 它返回 col2.value + ':1' 并且如果它是一个 b 它返回 col2.value + ':2' 作为一个单一的字符串 我试图写一个函数,其中

def return_stg(x):
    if df[df[col2] == x][col1] == "a":
        return x + ':1'
    if df[df[col2] == x][col1] == "b":
        return x + ':2'
df[col3] = df[col2].apply(return_stg)

但它会抛出一个 ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。

但如果我只输入 df[df[col2] == "stg"][col1] == "a" 来检查它,它会返回 True,所以我看不出它是如何模棱两可的

基本上我需要对每一行进行检查,检查 col1 中的值,如果它是 'a',则返回 col2 与字符串 ':1' 等连接的值

【问题讨论】:

  • 所以你需要apply的循环慢速解决方案?
  • 我问是因为有点惊讶,这是什么原因?

标签: python pandas lambda


【解决方案1】:

一种解决方案:

df["col3"] = np.where(df["col1"] == "a", df["col2"] + ':1', df["col2"] + ':2')

输出:

 col1   col2     col3
0   a    stg    stg:1
1   b    etc    etc:2
2   a    xyz    xyz:1
3   b    wha    wha:2

第一个答案,速度较慢(见 cmets):

在您提出的代码中,在函数 return_stg() 内,您引用​​完整的数据集 df 而不是当前行 x(因此您将数据集与单个值进行比较)。这就是抛出ValueError 的原因。我会这样纠正它:

def return_stg(x):
    if x["col1"] == "a":
        return x["col2"] + ':1'
    else:
        return x["col2"] + ':2'
df["col3"] = df.apply(return_stg, axis=1)

你可以写成一行:

df["col3"] = df.apply(lambda x: x["col2"] + ':1' if x["col1"] == "a" else x["col2"] + ':2', axis=1)

【讨论】:

  • 不幸的是,这个解决方案真的很糟糕,因为使用apply 什么是引擎盖下的循环。总是有必要避免它。
  • 感谢您的关注和链接,我编辑了我的答案。
  • np.where() 不能使用什么? (指你的老cmets)
  • 是的,np.where 是您解决方案的最佳选择。
【解决方案2】:

这是最好的不使用循环解决方案,因此您需要避免apply(引擎盖下的循环)或fors 和numpy.select

m1 = df['col1'] == "a"
m2 = df['col1'] == "b"

df['col3'] = np.select([m1, m2], [df['col2'] + ':1', df['col2'] + ':2'], df['col2'])

print (df)
  col1 col2   col3
0    a  stg  stg:1
1    b  etc  etc:2
2    a  xyz  xyz:1
3    b  wha  wha:2

如果需要更多动态解决方案,则意味着col1的第一个唯一值是1,第二个是2,第三个是3使用factorize

s = pd.Series(pd.factorize(df['col1'])[0], index=df.index).add(1).astype(str)
df['col3'] = df['col2'] + ':' + s
print (df)
  col1 col2   col3
0    a  stg  stg:1
1    b  etc  etc:2
2    a  xyz  xyz:1
3    b  wha  wha:2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    相关资源
    最近更新 更多