python - 根据另一列中的组和条件填充列

标签 python python-3.x pandas dataframe numpy

考虑下面的 Pandas DataFrame

df = pd.DataFrame({'Make': ['Tesla','Tesla','Tesla','Toyota','Ford','Ford','Ford','BMW','BMW','BMW','Mercedes','Mercedes','Mercedes','Jeep','Jeep','Jeep'],
                   'Type': ['Model X','Model X','Model X','Corolla','Bronco','Bronco','Mustang','3 Series','3 Series','7 Series','C-Class','C-Class','S-Class','Wrangler','Compass','Patriot'],
                   'Year': [2015, 2015, 2015, 2017, 2018, 2018, 2020, 2015, 2015, 2017, 2018, 2018, 2020,2020,2021,2020],
                   'Price': [85000, 90000, 95000, 20000, 35000, 35000, 45000, 40000, 40000, 65000, 50000, 50000, 75000,60000,45000,40000],
                   'Color': ['White','White','White','Red','Blue','Blue','Yellow','Silver','Silver','Black','White','White','Black','Grey','Brown','Green'],
                   'Code'  : ['TSLABG','TSLA',None,'TYTA','FRD','_BG',None,None,'BMW','BMW','MercedesBG','Mercedes_BG','MercedesBG',None,'_BG','JeepBG']
                  })
df
     Make   Type       Year Price   Color   Code
0   Tesla   Model X    2015 85000   White   TSLABG
1   Tesla   Model X    2015 90000   White   TSLA
2   Tesla   Model X    2015 95000   White   None
3   Toyota  Corolla    2017 20000   Red     TYTA
4    Ford   Bronco     2018 35000   Blue    FRD 
5    Ford   Bronco     2018 35000   Blue    _BG
6    Ford   Mustang    2020 45000   Yellow  None
7     BMW   3 Series   2015 40000   Silver  None
8     BMW   3 Series   2015 40000   Silver  BMW
9     BMW   7 Series   2017 65000   Black   BMW
10 Mercedes C-Class    2018 50000   White   MercedesBG
11 Mercedes C-Class    2018 50000   White   Mercedes_BG
12 Mercedes S-Class    2020 75000   Black   MercedesBG
13   Jeep   Wrangler   2020 60000   Grey    None
14   Jeep   Compass    2021 45000   Brown   _BG
15   Jeep   Patriot    2020 40000   Green   JeepBG

我正在尝试更新Code栏目基于Make 。如果Code列有 None ,必须根据 Code 的其他值正确填写相同的列Make 。换句话说,如果有的话MakeCode Code中定义该值应用于填充 None 的列Code 中的值列,也如果 BG_BG附加到相同 Make 的任何代码值,所有Code值应附加 BG_BG分别为相同的MakeBG优先于_BG

BMW没有BG_BG对于已经存在的BMW代码值,当替换 None 时它不会附加 BG_BG 。福特 _BG存在值之一和 FRD存在另一个值,因此所有 Code Ford 的值应该是FRD_BG .

对于梅赛德斯,有 Code值为 BG附加到代码中,如果有的话 Code值(value)在于拥有 _前置于BG_应从 Code 中删除值(value)

类似地 Jeep我期望输出为 JeepBG对于所有 Jeep Make因为如果出现“BG”和“_BG”BG优先于_BG

每个 make 肯定会在组的条目之一中指定一个代码值。

我尝试过的解决方案

code = (df['Code'].str.split('(BG|_BG)', expand=True).add_prefix('part').replace('-', None).groupby(df['Make']).transform('first').fillna('').agg(''.join, axis=1))
df['Code'] = code
df

我得到的输出有 _BG正在填充所有 Jeep Code它应该是JeepBG .

     Make   Type       Year Price   Color   Code
0   Tesla   Model X    2015 85000   White   TSLABG
1   Tesla   Model X    2015 90000   White   TSLABG
2   Tesla   Model X    2015 95000   White   TSLABG
3   Toyota  Corolla    2017 20000   Red     TYTA
4    Ford   Bronco     2018 35000   Blue    FRD_BG
5    Ford   Bronco     2018 35000   Blue    FRD_BG
6    Ford   Mustang    2020 45000   Yellow  FRD_BG
7     BMW   3 Series   2015 40000   Silver  BMW
8     BMW   3 Series   2015 40000   Silver  BMW
9     BMW   7 Series   2017 65000   Black   BMW
10 Mercedes C-Class    2018 50000   White   MercedesBG
11 Mercedes C-Class    2018 50000   White   MercedesBG
12 Mercedes S-Class    2020 75000   Black   MercedesBG
13   Jeep   Wrangler   2020 60000   Grey    _BG
14   Jeep   Compass    2021 45000   Brown   _BG
15   Jeep   Patriot    2020 40000   Green   _BG

预期输出是:

     Make   Type       Year Price   Color   Code
0   Tesla   Model X    2015 85000   White   TSLABG
1   Tesla   Model X    2015 90000   White   TSLABG
2   Tesla   Model X    2015 95000   White   TSLABG
3   Toyota  Corolla    2017 20000   Red     TYTA
4    Ford   Bronco     2018 35000   Blue    FRD_BG
5    Ford   Bronco     2018 35000   Blue    FRD_BG
6    Ford   Mustang    2020 45000   Yellow  FRD_BG
7     BMW   3 Series   2015 40000   Silver  BMW
8     BMW   3 Series   2015 40000   Silver  BMW
9     BMW   7 Series   2017 65000   Black   BMW
10 Mercedes C-Class    2018 50000   White   MercedesBG
11 Mercedes C-Class    2018 50000   White   MercedesBG
12 Mercedes S-Class    2020 75000   Black   MercedesBG
13   Jeep   Wrangler   2020 60000   Grey    JeepBG
14   Jeep   Compass    2021 45000   Brown   JeepBG
15   Jeep   Patriot    2020 40000   Green   JeepBG

最佳答案

让我们分步骤进行,因为有很多要求

首先,让我们定义列 is_bgisbg,这将在整个过程中为我们提供帮助:

grouper = df.groupby('Make')['Code']
df['is_bg'] = grouper.transform(lambda s: s.str.endswith('_BG').astype(bool))
df['isbg']  = grouper.transform(lambda s: s.str.endswith('BG') 
                                   & ~s.str.endswith('_BG').astype(bool))

现在,让我们删除 _BGBG 后缀,以便我们可以找到每个 Code 的唯一标识符:

df.loc[df.isbg,  'Code'] = df.loc[df.isbg,  'Code'].str[:-2]
df.loc[df.is_bg, 'Code'] = df.loc[df.is_bg, 'Code'].str[:-3]

现在,我们创建一个映射器并分配:

mapper = df.groupby('Make').apply(lambda s:
                           # Retrieve the unique code
                           s.loc[s['Code'].str.len() > 1,'Code'].iloc[0] + 
                           # Append BG if `isbg`
                           ('BG' if s.isbg.any() else 
                           # Otherwise, append _BG if `is_bg`
                           ('_BG' if s.is_bg.any() else '')))
df['New_Code'] = df['Make'].map(mapper)

请注意,这里有一个假设,对于每个 Make,我们在 Code 中只有一个条目,在拥有 _BGBG 已删除,不会是空格或 None。如果情况并非如此,则问题不明确,您需要探索如何查找唯一的代码标识符。


        Make      Type  Year  Price      Code   isbg  is_bg    New_Code
0      Tesla   Model X  2015  85000      TSLA   True  False      TSLABG
1      Tesla   Model X  2015  90000      TSLA  False  False      TSLABG
2      Tesla   Model X  2015  95000      None  False  False      TSLABG
3     Toyota   Corolla  2017  20000      TYTA  False  False        TYTA
4       Ford    Bronco  2018  35000       FRD  False  False      FRD_BG
5       Ford    Bronco  2018  35000            False   True      FRD_BG
6       Ford   Mustang  2020  45000      None  False  False      FRD_BG
7        BMW  3 Series  2015  40000      None  False  False         BMW
8        BMW  3 Series  2015  40000       BMW  False  False         BMW
9        BMW  7 Series  2017  65000       BMW  False  False         BMW
10  Mercedes   C-Class  2018  50000  Mercedes   True  False  MercedesBG
11  Mercedes   C-Class  2018  50000  Mercedes  False   True  MercedesBG
12  Mercedes   S-Class  2020  75000  Mercedes   True  False  MercedesBG
13      Jeep  Wrangler  2020  60000      None  False  False      JeepBG
14      Jeep   Compass  2021  45000            False   True      JeepBG
15      Jeep   Patriot  2020  40000      Jeep   True  False      JeepBG

关于python - 根据另一列中的组和条件填充列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76220259/

相关文章:

python - 如何利用 GPU 将大型 dask 数组 (numpy.ndarray) 写入 Zarr 文件?

python - 将txt文件解析为2个csv文件

python - 如何以用户身份使用 Slack API 上传文件?

python - 使用 NLTK 创建新语料库

python - 如何在 Python (Pandas) 中重命名特定范围的列

python - 插入行并添加缺失的数据

python - 在同一对象上多处理独立函数的最有效方法

python - 如何在 PyQt5 中嵌入表格

python - 当 MongoDB 用作数据库时使用哪个 python web 框架(django 或 django-norel 或 Pyramid )

python-3.x - pyttsx 和 gTTS 模块错误