bugfix> python > 投稿

私は3つのフィールドを持っています1 :)請求書番号2 :)請求書補助番号と3 :)請求書金額。すべての一意の請求書番号には、複数の請求書補助番号が含まれる場合があります。要件は、請求書サブ番号が1200および2100で始まる場合、複数行の一意の請求書番号ごとに、「1200および2100の両方が存在する」というダミー列を導入する必要があることです。 1200から始まるダミー列は「has only 1200」である必要があります。それ以外の場合、「has only 2100」と表示されます。以下に例を示します

S.no Invoice #    Invoice Sub Number    Amount    Dummy
----------------------------------------------
 1.   1234              1230             $100  Both 2100 and 1200 exists
 2.   1234              2100             $100  Both 2100 and 1200 exists
 3.   1234              1200             $100  Both 2100 and 1200 exists
 4.   1245              5430             $50   Only 1200 exists 1245      
 5.   1245              1200             $80   Only 1200 exists

私はPythonで次のコマンドを試しましたが、動作していません 使用するコマンド

df1= df
df1['Invoice #'] = df1['Invoice #'].astype(object)
df['Invoice sub Number'] = df['Invoice sub Number'].astype(str)
df1= df1.groupby(df['Invoice sub Number','Invoice #'].size().groupby(level=0).size())
df1['dummy']= np.where(df1['Invoice sub Number'].str.startswith ('1200'),'Contains 1200 only',
               np.where(df1['Invoice sub Number'].str.startswith ('2100'),'Contains 2100 only',
                        np.where((df1['Invoice sub Number'].str.startswith ('1200'))&(df1['Invoice sub Number'].str.startswith ('2100')),
                                 'Contains both 1200 and 2100','Contains neither 1200 nor 2100')))

エラーが発生しています:- KeyError: ('Invoice sub Number', 'Invoice #')

回答 1 件
  • GroupBy.any を使用することをお勧めします   transform と  少なくとも1つの True をチェックするため sグループごとに、条件 numpy.select による列 :

    使用する:

    print (df)
        Invoice #  Invoice sub Number  Amount
    0         123                1234     100
    1         123                2345     200
    2         123                3456     300
    3         123                1200     400
    4         123                2100     500
    5        1234                1245     600
    6        1234                2344     700
    7        1234                1200     800
    8        2345                 345     900
    9        2345                2100    1000
    10       2345                2458    1100
    11       6789                2345    1200
    12       6789                3421    1300
    13       6789                1234    1400
    m1 = df['Invoice sub Number'].astype(str).str.startswith('1200')    
    m2 = df['Invoice sub Number'].astype(str).str.startswith('2100')
    m11 = m1.groupby(df['Invoice #']).transform('any')
    m22 = m2.groupby(df['Invoice #']).transform('any')
    masks =[ m11 & m22 , m11, m22]
    vals = ['Contains both 1200 and 2100', 'Contains 1200 only','Contains 2100 only']
    default = 'Contains neither 1200 nor 2100'         
    df['dummy'] = np.select(masks, vals, default=default)
    
    

    print (df)
        Invoice #  Invoice sub Number  Amount                           dummy
    0         123                1234     100     Contains both 1200 and 2100
    1         123                2345     200     Contains both 1200 and 2100
    2         123                3456     300     Contains both 1200 and 2100
    3         123                1200     400     Contains both 1200 and 2100
    4         123                2100     500     Contains both 1200 and 2100
    5        1234                1245     600              Contains 1200 only
    6        1234                2344     700              Contains 1200 only
    7        1234                1200     800              Contains 1200 only
    8        2345                 345     900              Contains 2100 only
    9        2345                2100    1000              Contains 2100 only
    10       2345                2458    1100              Contains 2100 only
    11       6789                2345    1200  Contains neither 1200 nor 2100
    12       6789                3421    1300  Contains neither 1200 nor 2100
    13       6789                1234    1400  Contains neither 1200 nor 2100
    
    

あなたの答え