Pandas 根据另一行中同一列的值替换列的值

问题描述 投票:0回答:1

我正在尝试将数据帧列的值替换为同一列但来自另一行的值。

类型为“TO_REPLACE”的国家/地区的 ID 必须替换为类型为“ORIGINAL”的同一国家/地区的 ID。

DF 示例:

ID     NAME        TYPE
---
ID1    COUNTRY1    ORIGINAL       <-- ORIGINAL of COUNTRY1 (ID1)
ID2    COUNTRY1    TO_REPLACE1    <-- ID must be ID1
ID3    COUNTRY1    TO_REPLACE2    <-- ID must be ID1
...
ID4    COUNTRYX    TO_REPLACE1    <-- ID must be ID6
ID5    COUNTRYX    TO_REPLACE2    <-- ID must be ID6
ID6    COUNTRYX    ORIGINAL       <-- ORIGINAL of COUNTRYX (ID6)

我需要: 如果-TYPE-是“TO_REPLACE1”或“TO_REPLACE2”,则找到-NAME-和-TYPE-“ORIGINAL”并将“ORIGINAL ID”放在ID上。 在此示例的末尾,所有 -NAME- COUNTRY1 必须为 ID1(“原始”ID),而 COUNTRYX 必须为 ID6。

结果:

ID     NAME        TYPE
---
ID1    COUNTRY1    ORIGINAL
ID1    COUNTRY1    TO_REPLACE1    <-- ID replaced
ID1    COUNTRY1    TO_REPLACE2    <-- ID replaced
...
ID6    COUNTRYX    TO_REPLACE1    <-- ID replaced
ID6    COUNTRYX    TO_REPLACE2    <-- ID replaced
ID6    COUNTRYX    ORIGINAL

经过多次尝试,最接近的是这个:

df.loc[(df['TYPE'].isin(['TO_REPLACE1', 'TO_REPLACE2']), 'ID'] = df.loc[df['TYPE'] == 'ORIGINAL', 'ID'].values[0]

但仅替换为找到的第一个“原始 ID”。

pandas dataframe multiple-conditions
1个回答
0
投票

您可以

mask
/
where
并使用
groupby.transform
:

df['ID'] = (df['ID']
 .where(df['TYPE'].eq('ORIGINAL'))
 .groupby(df['NAME']).transform('first')
)

或与

map
:

df['ID'] = df['NAME'].map(df[df['TYPE'].eq('ORIGINAL')].set_index('NAME')['ID'])

如果您确实需要匹配“ORIGINAL”和“TO_REPLACE”(假设其他值),则可以使用更通用的方法:

df['ID'] = (df['ID']
 .mask(df['TYPE'].str.startswith('TO_REPLACE'))
 .fillna(df['NAME'].map(df[df['TYPE'].eq('ORIGINAL')]
                        .set_index('NAME')['ID']))
)

输出:

    ID      NAME         TYPE
0  ID1  COUNTRY1     ORIGINAL
1  ID1  COUNTRY1  TO_REPLACE1
2  ID1  COUNTRY1  TO_REPLACE2
3  ID6  COUNTRYX  TO_REPLACE1
4  ID6  COUNTRYX  TO_REPLACE2
5  ID6  COUNTRYX     ORIGINAL
© www.soinside.com 2019 - 2024. All rights reserved.