【问题标题】:Checking if a string is present in various columns. If present change another variable in pandas检查字符串是否存在于各个列中。如果存在,请更改 pandas 中的另一个变量
【发布时间】:2019-07-17 05:55:31
【问题描述】:

我正在尝试逐行使用条件,如果为真,则逐行更改我的数据框中的变量。

这里是一些示例数据:

import pandas as pd

data = {'grade' : [1,2,3], 'new_grade': [np.nan, np.nan, np.nan], 'pred1': ['yes','no-x','no'], 'pred2': ['yes-x','yes-x', 'yes'], 'pred3': ['yes','no-x','yes']}

df = pd.DataFrame(数据) 打印(df)

   grade  new_grade pred1  pred2 pred3
0      1        NaN   yes  yes-x   yes
1      2        NaN  no-x  yes-x  no-x
2      3        NaN    no    yes   yes

在示例中,如果 pred1、pred2 或 pred3 中的任何一个中都没有“x”,我希望“new_grade”保持不变。如果 pred1、pred2 或 pred3 中的每个变量都有一个“x”,我想从“grade”中减去 1,并将其保存为“new_grade”。

我试过了,但它没有给我想要的结果:

df['new_grade'] = np.where('x' not in str(df[['pred1', 'pred2', 'pred3',]]),  df['grade'], df['grade']-1)

这是所需的输出:

   grade  new_grade pred1  pred2 pred3
0      1          1   yes  yes-x   yes
1      2          1  no-x  yes-x  no-x
2      3          3    no    yes   yes

不确定是否需要使用 iterrows() 进行 for 循环?

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • 对不起,我搞砸了所需的输出。现在是正确的

标签: python pandas conditional-statements


【解决方案1】:

我们可以使用df.filter 获取所有pred 列并检查它们是否包含x。然后使用np.where.sub 有条件地从grade 中减去1:

m = df.filter(like='pred').apply(lambda x: x.str.contains('x'), axis=1).all(axis=1)

df['new_grade'] = np.where(m, df['grade'].sub(1), df['grade'])

输出

   grade  new_grade pred1  pred2 pred3
0      1          1   yes  yes-x   yes
1      2          1  no-x  yes-x  no-x
2      3          3    no    yes   yes

NaN 的输出:

   grade  new_grade pred1  pred2 pred3  pred4
0      1          1   yes  yes-x   yes    NaN
1      2          1  no-x  yes-x  no-x    NaN
2      3          3    no    yes   yes    NaN

【讨论】:

  • 如果假设我添加了一个只有 np.nan 的 pred4,有没有办法让它工作?有没有办法在该列中添加相同的结果?
  • 是的,请参阅编辑@Jake。 .all方法默认跳过NaN,见docs
【解决方案2】:

在您的情况下,我们可以使用contains

df['new_grade']=df.grade-df.loc[:,'pred1':].apply(lambda x : x.str.contains('-x')).all(1)
df
Out[591]: 
   grade  new_grade pred1  pred2 pred3
0      1          1   yes  yes-x   yes
1      2          1  no-x  yes-x  no-x
2      3          3    no    yes   yes

【讨论】:

  • 如果假设我添加了一个只有 np.nan 的 pred4,有没有办法让它工作?有没有办法在该列中添加相同的结果?
【解决方案3】:

试试这个:

cond1 = df.pred1.str.endswith('x')
cond2 =  df.pred2.str.endswith('x')
cond3 = df.pred3.str.endswith('x')
df['new_grad'] = df['grade'].where(~(cond1 & cond2 & cond3), df['grade'] - 1)

【讨论】:

  • 如果假设我添加了一个只有 np.nan 的 pred4,有没有办法让它工作?有没有办法在该列中添加相同的结果?
  • @Jake,取决于,如果您不考虑这个新列,那么解决方案应该可以正常工作
猜你喜欢
  • 2021-08-18
  • 1970-01-01
  • 2022-01-23
  • 2011-03-24
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
相关资源
最近更新 更多