2015-10-28 24 views
6

Sto cercando di scoprire se Date cade nel PromoInterval in una cornice di dati.Applicare la funzione con args nei panda

print dset1 

     Store Date PromoInterval 
1760 2 2013-05-04 Jan,Apr,Jul,Oct 
1761 2 2013-05-03 Jan,Apr,Jul,Oct 
1762 2 2013-05-02 Jan,Apr,Jul,Oct 
1763 2 2013-05-01 Jan,Apr,Jul,Oct 
1764 2 2013-04-30 Jan,Apr,Jul,Oct 

def func(a,b): 
    y = b.split(",") 
    z = {1:'Jan',2:'Feb',3:'Mar', 4:'Apr',5:'May',6:'Jun',7:'Jul',8:'Aug',9:'Sep', 
     10:'Oct',11:'Nov',12:'Dec'} 
    return (z[a] in y) 

dset1.apply(func, axis=1, args = (dset1['Date'].dt.month, dset1['PromoInterval'])) 

ha colpito alle errore di seguito: set

dset1.apply(func, axis=1, args = (dset1['Date'].dt.month, >dset1['PromoInterval'])) ('func() takes exactly 2 arguments (3 given)', u'occurred at index 1760')

dati:

{'Date': {1760: Timestamp('2013-05-04 00:00:00'), 
    1761: Timestamp('2013-05-03 00:00:00'), 
    1762: Timestamp('2013-05-02 00:00:00'), 
    1763: Timestamp('2013-05-01 00:00:00'), 
    1764: Timestamp('2013-04-30 00:00:00')}, 
'PromoInterval': {1760: 'Jan,Apr,Jul,Oct', 
    1761: 'Jan,Apr,Jul,Oct', 
    1762: 'Jan,Apr,Jul,Oct', 
    1763: 'Jan,Apr,Jul,Oct', 
    1764: 'Jan,Apr,Jul,Oct'}, 
'Store': {1760: 2, 1761: 2, 1762: 2, 1763: 2, 1764: 2}} 
+0

Credo che la parola chiave è '' non args' arg'. – TomAugspurger

+0

Scusa se ho aggiornato l'errore vecchio. – WoodChopper

+0

Gli argomenti aggiuntivi in ​​'args' vengono passati come argomenti dopo gli elementi del dataframe. Dal momento che si passano due argomenti aggiuntivi, si passano effettivamente tre argomenti in totale. – IanS

risposta

3

vorrei iniziare formattando la stringa di testo del mese utilizzando una funzione lambda sulla colonna 'Date':

df['Month'] = df['Date'].apply(lambda x: x.strftime('%b')) 

Poi vorrei sparare una funzione lambda su axis=1 che significa che agisce sull'asse x il dataframe. Qui ho semplicemente controllare se 'Month' è in 'PromoInterval'

df[['PromoInterval', 'Month']].apply(lambda x: x[1] in x[0], axis=1) 

1760 False 
1761 False 
1762 False 
1763 False 
1764  True 
dtype: bool 
1

in realtà questo è perché la funzione prende 3 parametri, non due

def func(df,a,b): 
    print('---df----') 
    print(df) 
    print('---a---') 
    print(a) 
    print('---b---') 
    print(b) 
    y = b.split(",") 
    z = {1:'Jan',2:'Feb',3:'Mar', 4:'Apr',5:'May',6:'Jun',7:'Jul',8:'Aug',9:'Sep', 
     10:'Oct',11:'Nov',12:'Dec'} 
    return (z[a] in y) 

In [98]: 
dset1.apply(func, axis=1, args = (dset1['Date'].dt.month, dset1['PromoInterval'])) 

In [99]: 

---df---- 
Store        2 
Date    2013-05-04 00:00:00 
PromoInterval  Jan,Apr,Jul,Oct 
Name: 0, dtype: object 
---a--- 
0 5 
1 5 
2 5 
3 5 
4 4 
dtype: int64 
---b--- 
0 Jan,Apr,Jul,Oct 
1 Jan,Apr,Jul,Oct 
2 Jan,Apr,Jul,Oct 
3 Jan,Apr,Jul,Oct 
4 Jan,Apr,Jul,Oct 
Name: PromoInterval, dtype: object 

invece può fare il seguente

In [94]: 

def func(df): 
    y = df['PromoInterval'].split(",") 
    z = {1:'Jan',2:'Feb',3:'Mar', 4:'Apr',5:'May',6:'Jun',7:'Jul',8:'Aug',9:'Sep', 
    10:'Oct',11:'Nov',12:'Dec'} 
    return (z[df.Date.month] in y) 

In [95]: 
dset1.apply(func, axis=1) 



Out[112]: 
0 False 
1 False 
2 False 
3 False 
4  True 
dtype: bool 
2

Una soluzione è quella di rendere la vostra funzione prendere una fila invece di elementi:

def func(row): 
    y = row[2].split(",") 
    z = {1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun', 
     7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec'} 
    return (z[row[1].month] in y) 

Si può quindi applicare semplicemente:

df['Result'] = df.apply(func, axis=1) 

Nota: la funzione utilizza .month perché io date convertite in oggetti datetime con pd.to_datetime.

Problemi correlati