【问题标题】:Apply function only on specific rows AND columns using Python Pandas使用 Python Pandas 仅在特定行和列上应用函数
【发布时间】:2021-09-24 05:47:40
【问题描述】:

我在下面有一个数据框:

df = {'a': [1, 2, 3],
      'b': [77, 88, 99],
      'c1': [1, 1, 1],
      'c2': [2, 2, 2],
      'c3': [3, 3, 3]}
df = pd.DataFrame(df)

还有一个功能:

def test_function(row):
    return row['b']

如何将此函数应用于“c”列(即 c1、c2 和 c3),但仅适用于“a”值与“c”列的第二个字符匹配的特定行?

例如,对于第一行,'a' 的值为 1,所以对于第一行,我想在列 'c1' 上应用这个函数。

对于第二行,'a' 的值为 2,所以对于第二行,我想在列 'c2' 上应用这个函数。其余行以此类推。

期望的最终结果应该是:

df_final = {'a': [1, 2, 3],
            'b': [77, 88, 99],
            'c1': [77, 1, 1],
            'c2': [2, 88, 2],
            'c3': [3, 3, 99]}
df_final = pd.DataFrame(df_final)

【问题讨论】:

    标签: python pandas dataframe function lambda


    【解决方案1】:

    Series.mask 与由DataFrame.filter 过滤的比较c 列一起使用,如果匹配则由b 的值替换:

    c_cols = df.filter(like='c').columns
    
    def test_function(row):
        #for test integers from 0 to 9
        #m = c_cols.str[1].astype(int) == row['a']
        #for test integers from 0 to 100
        m = c_cols.str.extract('(\d+)', expand=False).astype(int) == row['a']
        row[c_cols] = row[c_cols].mask(m, row['b'])
        return row
    
    df = df.apply(test_function, axis=1)
    print (df)
       a   b  c1  c2  c3
    0  1  77  77   2   3
    1  2  88   1  88   3
    2  3  99   1   2  99
    

    广播的非循环更快的替代方案:

    arr = c_cols.str.extract('(\d+)', expand=False).astype(int).to_numpy()[:, None]
    m = df['a'].to_numpy() == arr
    df[c_cols] = df[c_cols].mask(m, df['b'], axis=0)
    

    【讨论】:

    • 谢谢耶斯瑞尔!我认为它快到了,但可以使用“test_function”功能吗?我尝试使用 .apply 函数,但它仍然给我一些错误。由于断言错误,我也更新了问题。感谢您的提醒!
    • @Alvin - 在c 列中只有整数0 to 9 ?答案已编辑,您可以检查一下吗?
    • 我的实际数据中的整数范围是1到100。这个函数有效!非常感谢您的帮助 :) 我尝试了 for 循环“for i in df['a']”,但没有成功。不知道我必须编辑函数本身。
    • @Alvin - 匹配 1 的解决方案已更改为 100。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 2021-03-29
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多