如何使用 Pandas 以定义的规则填充某些单元格?

How to use Pandas to fill some cells with a defined rule?

这是真实的样本数据。

df = pd.DataFrame({'P/N':['302-462-326','302-462-012','302-462-009'],
                  'Description':['CAP CER 0402 100pF 5% 50V','CAP CER 0402 6.8pF 0.25pF 50V','CAP CER 0402 3.9pF 0.25pF 50V'],
                  'Supplier.0':['MURATA','AVX Corporation','AVX Corporation'],
                  'Supplier PN.0':['GRM1555C1H101JA01D',np.nan,'04025A3R9CAT2A'],
                  'Supplier.1':[np.nan,'KEMET',np.nan],
                  'Supplier PN.1':['CC0402JRNPO9BN101','C0402C689C5GACTU',np.nan],
                  'Supplier.2':['Murata Electronics North America',np.nan,np.nan],
                  'Supplier PN.2':['GRM1555C1H101JA01J',np.nan,np.nan]
                  })

供应商供应商 PN 在列中配对。要求是如果Suppliersupplier PN其中一个为空,但另一个不为空,那么我们必须填写'NOT CLEAR' 在空单元格中。 当 Supplier 和 Supplier PN 都为空时,我们需要将单元格保持为空。

How to use Pandas to get the expected result which just as the picture below?Thanks.

The real data has many rows and columns may be reached to Supplier.20 and Supplier PN.20.

遍历相关供应商列并使用 np.where 和 .isna() / .notna()

import pandas as pd
import numpy as np
df = pd.DataFrame({'P/N':['302-462-326','302-462-012','302-462-009'],
          'Description':['CAP CER 0402 100pF 5% 50V',
          'CAP CER 0402 6.8pF 0.25pF 50V',
          'CAP CER 0402 3.9pF 0.25pF 50V'],
          'Supplier.0':['MURATA','AVX Corporation','AVX Corporation'],
          'Supplier PN.0':['GRM1555C1H101JA01D',np.nan,'04025A3R9CAT2A'],
          'Supplier.1':[np.nan,'KEMET',np.nan],
          'Supplier PN.1':['CC0402JRNPO9BN101','C0402C689C5GACTU',np.nan],
          'Supplier.2':['Murata Electronics North America',np.nan,np.nan],
          'Supplier PN.2':['GRM1555C1H101JA01J',np.nan,np.nan]
          })
cols = df.columns
i, j = 0, 0
for col in cols:
    if 'Supplier.' in col:
        col_var1 = f'Supplier.{i}'
        col_var2 = f'Supplier PN.{i}'
        df[col_var1] = np.where(df[col_var1].isna() & df[col_var2].notna(),
                                'NOT CLEAR',
                                df[col_var1])
        i += 1
    elif 'Supplier PN.' in col:
        col_var1 = f'Supplier.{j}'
        col_var2 = f'Supplier PN.{j}'
        df[col_var2] = np.where(df[col_var2].isna() & df[col_var1].notna(),
                                'NOT CLEAR',
                                df[col_var2])
        j += 1
df

另一种方法是使用 wide_to_long 数据框进行逆透视,然后检查 notna 的总和是否为 1 然后 fillna else dont ,然后再次转回,如果您有许多供应商和供应商 PN 的组合,这将有所帮助.

unpivotted_df = (pd.wide_to_long(df,['Supplier','Supplier PN'],
                 ['P/N','Description'],'idx',sep='.'))

cond = unpivotted_df.notna().sum(1).eq(1)
unpivotted_df[:]=np.where(cond[:,None],unpivotted_df.fillna('NOT CLEAR'),unpivotted_df)
out = unpivotted_df.unstack().sort_index(level=1,axis=1).reindex(df[['P/N','Description']])
out.columns=out.columns.map('{0[0]}.{0[1]}'.format) 

这是 unpivoted_dffillna 之后的样子: