2

我有一个数据框和一个函数,我想通过 pandas.apply 将其应用于多个列。目前我正在使用 for 循环,我想用一行代码替换它。

这是我的数据框:

d1 = {'id': [1, 1, 2], 'event': ['e', 'c', 'e'], 'var1': [1, 2, 2], 'time_difference': [0, 5, 2]}
df1 = pd.DataFrame(data=d1)
...
>> df1 
   id event  var1  time_difference
0   1     e     1                0
1   1     c     2                5
2   2     e     2                2

这是我要应用的功能:

def merge_based_on_timelimit(row):
    return row[column_of_interest] if row['time_difference'] <= 1\
        else pd.NA

这些是我感兴趣的列(我想在其上应用函数):

columns_of_interest = ['event', 'var1']

目前,我正在通过 for 循环将我的函数应用于所有感兴趣的列:

for column_of_interest in columns_of_interest:
    df1[column_of_interest] = df1.apply(merge_based_on_timelimit, axis=1)

但是,我正在寻找一种方法来跳过循环,而是将我的函数直接应用于所有感兴趣的列。我怎样才能做到这一点?到目前为止,我已经尝试了以下方法:

df1[columns_of_interest] = df1[columns_of_interest].apply(merge_based_on_timelimit, axis=1)

这返回了以下错误:

...
redcap[columns_of_interest] = redcap[columns_of_interest].apply(merge_based_on_timelimit, axis=1)
...
KeyError: 'time_difference'
4

1 回答 1

1

在我看来,这里apply没有必要,DataFrame.loc通过反转掩码使用设置值> 1

df1.loc[df1['time_difference'] > 1, columns_of_interest] = pd.NA

print (df1)
   id event  var1  time_difference
0   1     e     1                0
1   1  <NA>  <NA>                5
2   2  <NA>  <NA>                2

您的解决方案可以通过以下方式更改:

def merge_based_on_timelimit(row):
    #added s to column_of_interest
    return row[columns_of_interest] if row['time_difference'] <= 1\
        else pd.NA
columns_of_interest = ['event', 'var1']

#added column time_difference to list
df1[columns_of_interest] = df1[columns_of_interest + ['time_difference']].apply(merge_based_on_timelimit, axis=1)

print (df1)
   id event  var1  time_difference
0   1     e     1                0
1   1  <NA>  <NA>                5
2   2  <NA>  <NA>                2
于 2021-01-27T10:13:23.560 回答