根据 Pandas 中不同行的其他列中的值比较将值应用于列

Applying values to a column based on value comparison in other columns across different rows in Pandas

我已经在 Internet 上搜索了我的问题,但没有完全相同的内容。我是 Pandas.

的新手

我有一个巨大的数据框,大约有 80 万行。在 800K 行中,有 200K 行是重复的,表明车主在同一 SSN 下拥有多辆汽车(由于拼写等原因可能有不同的名称)。例如,下面是我的数据框。

SSN 是确定他们是同一个人的关键,尽管名字可能不同(或略有不同):

SSN_ID   Name              Registration_Number Brand       Car         Year    Eligible  Status   Channel 
00001    Baron Zemo        SKV2017             Toyota      86          2020    1         2        Call
00001    Baron Zimo        SKV1999             Subaru      BRZ         2012    1         0        Call
00002    Steve Rogers      SHD2012             Cadillac    deVille     1970    1         0        Call
00003    Bucky Barnes      MTL9841             Ford        Boss 429    1970    1         0        Call
00004    Tony Stark        IRN0007             Audi        R8          2013    1         1        Apps
00005    Wanda Maximoff    SCR1080             Hyundai     i-30N       2020    1         1        Apps 
00004    Tony Stank        ILY3000             Audi        e-Tron GT   2020    1         0        Call
00001    Beron Zemo        SKV0800             Audi        TT-RS       2018    1         1        Apps

第'Channel'栏是进行保险促销广告的渠道,第'Status'栏是客户参与的状态。

'Status' = 0, No call attempted
'Status' = 1, Answered, rejected/accepted the offer
'Status' = 2, Unanswered, line busy/not pick-up

之前的调用和推广都是以每辆车为单位进行的,因此出现了多次调用一个车主,一车一次的情况。例如上面的例子,Baron Zemo 将在单独的 time/day 为他的每辆车调用 3 次,因为他拥有 3 辆车。但是现在,尽管有多辆车,但管理层希望确保每个车主只被呼叫一次。

我想根据 'Status' 列值更新数据框中的 'Channel' 列。逻辑应该是这样的:

If 'Status' == 0 or 2, df[Channel] = 'Call'
If 'Status' == 1, df[Channel] = 'Apps'

但事实是,拥有多辆汽车的车主,有多个 'Status' 跨行。以 Zemo (SSN_ID : 00001) 和 Stark (SSN_ID : 00004) 为例。他们在 'Status' 列中有多个值,因为他们拥有多辆汽车。因此,我还需要根据其他行的 'Status' 值更新 'Channel' 列。

使用 .loc,我可以将数据帧分成 2 个,1 个用于拥有多辆车的车主,1 个用于拥有 1 辆车的车主。

df1= df.loc[df.duplicated(subset=['SSN_ID'], keep=False)].sort_values(by='SSN_ID', ascending=True)

df2= df.loc[~(df.duplicated(subset=['SSN_ID'], keep=False))]

df1 如下所示:

SSN_ID   Name              Registration_Number Brand       Car         Year    Eligible  Status   Channel 
00001    Baron Zemo        SKV2017             Toyota      86          2020    1         2        Call
00001    Baron Zimo        SKV1999             Subaru      BRZ         2012    1         0        Call
00001    Beron Zemo        SKV0800             Audi        TT-RS       2018    1         1        Apps
00004    Tony Stark        IRN0007             Audi        R8          2013    1         2        Apps
00004    Tony Stank        ILY3000             Audi        e-Tron GT   2020    1         0        Call

Eventho Zemo 有 3 个状态 (2,0,1),但由于我们已经在他的奥迪 TT-RS ('Status'== 1) 上给 Zemo 打电话并且他已经拒绝了这个提议,我们不应该懒得再给他打电话了(即使他还有另外两辆车),因此,列 'Channel' 将分配给 'Apps'.

至于 Stark,他有 2 个状态 (2,0),因为他没有接听电话 ('Status' == 2) ,我们会继续尝试给他打电话,直到他接听,或者拒绝或接受提议,因此,列 'Channel' 将分配给 'Call'.

但是,我不知道如何应用上面的逻辑。

df1 的最终期望结果如下:

SSN_ID   Name              Registration_Number Brand       Car         Year    Eligible  Status   Channel 
00001    Baron Zemo        SKV2017             Toyota      86          2020    1         2        Apps
00001    Baron Zimo        SKV1999             Subaru      BRZ         2012    1         0        Apps
00001    Beron Zemo        SKV0800             Audi        TT-RS       2018    1         1        Apps
00004    Tony Stark        IRN0007             Audi        R8          2013    1         2        Call
00004    Tony Stank        ILY3000             Audi        e-Tron GT   2020    1         0        Call

有没有一种方法可以跨行进行比较,并且只正确更新 'Channel' 列的值,而不更改数据框的形状(因为其他东西仍然需要它)?

非常感谢。

免责声明:我知道如果数据框的焦点基于 SSN_ID 而不是 Car/Registration 数字,它会更容易,但这是数据操作实践。

希望这能帮助您入门。这应该会为您提供您要查找的 channel 列。

d = {0:'Call',
1:'Apps'}

df['Channel'] = df['Status'].eq(1).groupby(df['SSN_ID']).transform('any').astype(int).map(d)