Python,根据每行第一列的值替换最后N列的所有整数

Python, replace all integers in the last N columns based on the value in the first column for each row

我想替换数据框最后 X 列中的值,将 NaN 替换为 0,将这些列中的任何整数替换为 1。X 列由 M 列中的值定义。

例如,如果我有一个有 2 个用户的 df:A 和 B 谁分别只在最后 (M) 1 和 2 个时段活跃。

A 仅在最后 1 个周期处于活动状态,B 在最后 2 个周期处于活动状态,因此我想在这些周期中将 NaN 替换为 0,并将任何整数替换为 1 以表明它们处于活动状态。

当前的结构是这样的,但扩展到 100 万以上的用户和 24 个周期,M 可以取 0 到 23 之间的值。

ID | M | P1 | P2 | P3  
A  | 1 | NaN| NaN| NaN    
B  | 2 | NaN| 4  | NaN  

如果只有最后 M 列中有 NaN,我想用 0 替换,或者如果在这些相同的列中有整数值,我想用 1 替换。

因此数据应如下所示:

ID | M | P1 | P2 | P3  
A  | 1 | NaN| NaN| 0    
B  | 2 | NaN| 1  | 0  

谢谢

尝试使用 df.apply() 方法如下:

import pandas as pd
import numpy as np 

df = pd.DataFrame(
    {
        'ID' : ['A', 'B'],
        'M' : [1, 2],
        'P1' : [np.nan, np.nan],
        'P2' : [np.nan, 4],
        'P3' : [np.nan, np.nan]
    }
)
print(df)

Returns:

  ID  M  P1   P2  P3
0  A  1 NaN  NaN NaN
1  B  2 NaN  4.0 NaN

然后我们在 n_cols 上使用 apply 函数,这是列数:

n_cols = 3
for i in range(n_cols):
    idx = 0 - (i+1)
    df.iloc[:, idx] = df.iloc[:, idx].apply(lambda x: 0.0 if np.isnan(x) else 1.0)
print(df)

哪个returns:

  ID  M  P1   P2   P3
0  A  1 0.0  0.0  0.0
1  B  2 0.0  1.0  0.0

要使用列 'M' 作为列数,请执行以下操作 - 请注意,这会比较慢,因为有两个循环:

for i, n_cols in enumerate(df['M'].values):
    for j in range(n_cols):
        idx = 0 - (j+1)
        df.iloc[i, idx] = 0.0 if np.isnan(df.iloc[i, idx]) else 1.0

哪个returns:

  ID  M  P1   P2   P3
0  A  1 NaN  NaN  0.0
1  B  2 NaN  1.0  0.0