在pandas中基于条件交换列值

6

我希望能按条件重新排列列。 假如国家是'日本',我需要将last_name和first_name颠倒位置。

df = pd.DataFrame([['France','Kylian', 'Mbappe'],
               ['Japan','Hiroyuki', 'Tajima'],
               ['Japan','Shiji', 'Kagawa'],
               ['England','Harry', 'Kane'],
               ['Japan','Yuya', 'Ohsako'],
               ['Portuguese','Cristiano', 'Ronaldo']],
              columns=['country', 'first_name', 'last_name'])

当前输出为

      country first_name last_name
0      France     Kylian    Mbappe
1       Japan   Hiroyuki    Tajima
2       Japan      Shiji    kagawa
3     England      Harry      Kane
4       Japan       Yuya    Ohsako
5  Portuguese  Cristiano   Ronaldo

我希望将其改为以下内容。
      country first_name last_name
0      France     Kylian    Mbappe
1       Japan     Tajima  Hiroyuki
2       Japan     Kagawa    Shinji
3     England      Harry      Kane
4       Japan     Ohsako      Yuya
5  Portuguese  Cristiano   Ronaldo

有什么想法吗?

4个回答

10

使用loc,并交换"country"列的值为"Japan"的行的"first_name"和"last_name"。

m = df['country'] == 'Japan'

df.loc[m, ['first_name', 'last_name']] = (
    df.loc[m, ['last_name', 'first_name']].values)
df    

      country first_name last_name
0  France      Kylian     Mbappe  
1  Japan       Tajima     Hiroyuki
2  Japan       Kagawa     Shiji   
3  England     Harry      Kane    
4  Japan       Ohsako     Yuya    
5  Portuguese  Cristiano  Ronaldo 

使用 renameupdate 的另一个选项:


mp = {'first_name': 'last_name', 'last_name': 'first_name'}
df.update(df.loc[m].rename(mp, axis=1))
df

      country first_name last_name
0  France      Kylian     Mbappe  
1  Japan       Tajima     Hiroyuki
2  Japan       Kagawa     Shiji   
3  England     Harry      Kane    
4  Japan       Ohsako     Yuya    
5  Portuguese  Cristiano  Ronaldo 

7
### check below   


 df['first_name'],df['last_name']=np.where(df['country']=='Japan',(df['last_name'],df['first_name']),(df['first_name'],df['last_name']))

输出:

   country      first_name     last_name
0   France      Kylian         Mbappe
1   Japan       Tajima         Hiroyuki
2   Japan       Kagawa         Shiji
3   England     Harry          Kane
4   Japan       Ohsako         Yuya
5   Portuguese  Cristiano  Ronaldo

1
使用 np.where
mask = df['country']=='Japan'

df['first_name1'] = np.where(mask, df['last_name'], df['first_name'])
df['last_name'] = np.where(mask, df['first_name'], df['last_name'])

df['first_name'] = df['first_name1']

df.drop('first_name1', axis=1, inplace=True)

输出:

    country first_name  last_name
0   France  Kylian  Mbappe
1   Japan   Tajima  Hiroyuki
2   Japan   Kagawa  Shiji
3   England Harry   Kane
4   Japan   Ohsako  Yuya
5   Portuguese  Cristiano   Ronaldo

1
不要使用 df['first_name'] = df['first_name1'],你可以直接使用 .rename 重命名列。你还应该考虑只计算一次带有“country”的条件,并将其保存到某个变量以供重复使用。 - cs95
但是 first_name1 列仍将存在,我是对的吧? - Sociopath
df.rename({'first_name1': 'first_name'}, axis=1)仅重命名列(而非复制它)。这比创建新列并删除旧列更好。 - cs95
@cs95 然后我的数据框将有两列名称为 first_name - Sociopath
1
我理解你的意思。一个建议是使用 df['last_name'] = np.where(mask, df.pop('first_name'), df.pop('last_name')),然后重命名就可以了。但是现在有太多事情要做了。也许现在这样就可以了。 - cs95

0

试试这个:

df['last_name1']=df.last_name
df.loc[df.country=='Japan','last_name']=df[df.country=='Japan']['first_name']
df.loc[df.country=='Japan','first_name']=df[df.country=='Japan']['last_name1']
df=df.drop(['last_name1'],axis=1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接