在其他列的特定条件下替换数据框中的项值

2024-09-28 23:23:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个数据框:

dx1      dx2    dx3     dx4     dxpoa1  dxpoa2  dxpoa3  dxpoa4
25041   40391                   Y       E       
25041   40391   25081           N       W       U       
25041   40391   42822   99681   1       N       Y       Y 

有两组列:dx和dxpoa。根据dxpoa中的某些值,我必须保留dx中的值或放弃它。对于dx中的每个值,该行中相应的dxpoa中都有一个值。例如:如果dxpoa=['Y'或'W'或'1'或'E'],则将dx值保留在相应行中,否则将其丢弃或用0填充。像第一行中的dxpoa1一样,是“Y”,因此dx1将保持原样。但第二行的dxpoa1是“N”,因此第二行的dx1的对应值将变为0。你知道吗


Tags: 数据dxdx2dx3dx1dx4dxpoa2dxpoa3
2条回答

这里有一个矢量化的方法来看待它(使用@vmg的方便的起始帧):

>>> N = len(df.columns)
>>> keep = df.iloc[:,-N//2:].isin(["Y", "W", "1", "E"]).values
>>> df.iloc[:,:N//2] = df.iloc[:,:N//2].where(keep, 0)
>>> df
     dx1    dx2    dx3    dx4 dxpoa1 dxpoa2 dxpoa3 dxpoa4
0  25041  40391      0      0      Y      E    NaN    NaN
1      0  40391      0      0      N      W      U    NaN
2  25041      0  42822  99681      1      N      Y      Y

它的作用是为最后的N//2列生成一个True和False的数组,如果值在列表中,则为True;如果值不在列表中,则为False(请注意,我假设1是字符串"1",而不是整数1):

>>> df.iloc[:,-N//2:]
  dxpoa1 dxpoa2 dxpoa3 dxpoa4
0      Y      E    NaN    NaN
1      N      W      U    NaN
2      1      N      Y      Y
>>> df.iloc[:,-N//2:].isin(["Y", "W", "1", "E"])
  dxpoa1 dxpoa2 dxpoa3 dxpoa4
0   True   True  False  False
1  False   True  False  False
2   True  False   True   True
>>> df.iloc[:,-N//2:].isin(["Y", "W", "1", "E"]).values
array([[ True,  True, False, False],
       [False,  True, False, False],
       [ True, False,  True,  True]], dtype=bool)

然后我们可以使用where来设置N//2列的值,将值保留在keep为真的位置,否则将其替换为0。你知道吗

给定这样构建的数据帧:

import pandas as pd
import numpy as np
df = pd.DataFrame({'dx1':[25041,25041,25041],
                   'dx2':[40391,40391,40391],
                   'dx3':[np.nan,25081,42822],
                   'dx4':[np.nan,np.nan,99681],
                   'dxpoa1':['Y','N','1'],
                   'dxpoa2':['E','W','N'],
                   'dxpoa3':[np.nan,'U','Y'],
                   'dxpoa4':[np.nan,np.nan,'Y']})

它给出:

    dx1     dx2     dx3     dx4    dxpoa1   dxpoa2  dxpoa3  dxpoa4
0   25041   40391   NaN     NaN     Y       E       NaN     NaN
1   25041   40391   25081   NaN     N       W       U       NaN
2   25041   40391   42822   99681   1       N       Y       Y

定义一个实现替换规则的函数。当引用列中的值不是“Y”、“W”、“1”或“E”时,这将用零替换目标列,正如我从您的描述中了解到的:

def subfunc(row,col_reference=None,col_target=None):
    if not row[col_reference] in ['Y','W','1','E']:
        row[col_target] = 0
    return row

然后对每行应用subfunc来迭代列名:

for colname in df.columns:
    if 'dxpoa' in colname:
        colid = colname.split('dxpoa')[1]
        df = df.apply(subfunc,axis=1,col_reference=colname,col_target='dx'+colid)

数据帧中的结果

    dx1     dx2     dx3     dx4     dxpoa1  dxpoa2  dxpoa3  dxpoa4
0   25041   40391   0       0       Y       E       NaN     NaN
1   0       40391   0       0       N       W       U       NaN
2   25041   0       42822   99681   1       N       Y       Y

相关问题 更多 >