【问题标题】:Trying to use apply to make operations over different keys in a Panda DataFrame尝试使用 apply 对 Panda DataFrame 中的不同键进行操作
【发布时间】:2021-01-10 21:47:32
【问题描述】:

我有一个看起来有点像这样的 Panda DataFrame:

df = pd.DataFrame({'ID' : ['O60829','O60341','Q9H1R3'], 'TOTAL_COVERAGE' : ['yes','yes','no'], 'BEG_D' : ['1','1','500'], 'END_D' : ['102','25','600'], 'BEG_S' : ['1','1','1'], 'END_S': ['102','25','458']})

我想遍历每一行,检查“TOTAL_COVERAGE”的值,如果是“是”,对其他值执行数学运算,即:

for index, row in df.iterrows():
    df['%']  = df.apply(lambda x : ((int(x['END_S'])*100)/int(x['END_D'])) if x['TOTAL_COVERAGE'] == 'yes' else '')

但我收到错误消息:KeyError: 'TOTAL_COVERAGE' 必须有一个我没有看到的简单修复。提前致谢!

【问题讨论】:

  • END_M在哪里?
  • Ups,这是一个错字!它就在这里,不在我的代码中
  • 旁注:FWIW,对非完全覆盖的 stuff 有一个百分比对报告很有帮助。在您的情况下为 76.33%。如果有的话,TOTAL_COVERAGE=yes/no 应该从 'END_S' == 'END_D' 的 % 或更好的值计算出来。

标签: python pandas lambda keyerror


【解决方案1】:

你可以不用iterrowsapply,直接等同:

df['%'] = ''
df.loc[df['TOTAL_COVERAGE'] == 'yes', '%'] = 
    df['END_S'].astype(int) * 100 / df['END_D'].astype(int)

【讨论】:

    【解决方案2】:

    你可以用矢量化的方法解决它,不需要iterrowsapply

    df['%'] = (df['END_S'].astype(int) * 100 / df['END_D'].astype(int)) \
                .where(df['TOTAL_COVERAGE'] == 'yes')
    
    df
    
    #       ID TOTAL_COVERAGE BEG_D END_D BEG_S END_S      %
    #0  O60829            yes     1   102     1   102  100.0
    #1  O60341            yes     1    25     1    25  100.0
    #2  Q9H1R3             no   500   600     1   458    NaN
    

    您收到 keyError 的原因是因为当您使用 apply 时,lambda x 的参数是一个列(熊猫系列),它不能用于通过其名称访问特定列。

    【讨论】:

    • 这似乎工作得很好,我理解这个问题。谢谢!一个后续问题是,如果我在该行之后使用 groupby,我似乎只保留具有“是”值的那些,而不是带有 NaN 的那个。为什么会这样?
    • 如果你按% 列分组,我认为这是因为 groupby 默认会删除 nan。如果要保留nan 行,可以在groupby 中设置dropna=False。即groupby(['%'], dropna=False).
    【解决方案3】:

    不需要iterrows()。条件逻辑可以使用numpy.where() 完成,以提供更有效的解决方案

    df = pd.DataFrame({'ID' : ['O60829','O60341','Q9H1R3'], 'TOTAL_COVERAGE' : ['yes','yes','no'], 'BEG_D' : ['1','1','500'], 'END_D' : ['102','25','600'], 'BEG_S' : ['1','1','1'], 'END_S': ['102','25','458']})
    df = (df
     .assign(pct=lambda x: np.where(x["TOTAL_COVERAGE"].eq("yes"),(x['END_S'].astype(int)*100)/x['END_D'].astype(int), np.nan))
     .rename(columns={"pct":"%"})
    )
    

    输出

         ID TOTAL_COVERAGE BEG_D END_D BEG_S END_S      %
     O60829            yes     1   102     1   102  100.0
     O60341            yes     1    25     1    25  100.0
     Q9H1R3             no   500   600     1   458    NaN
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      • 2019-01-25
      相关资源
      最近更新 更多