Reputation: 467
Here is the code I have:
def f(row):
if row['CountInBedDate'] == 1 and row['CountOutBedDate'] == 1:
SleepDate = row['DateInBed']
InBedTimeFinal = row['InBedTime']
OutBedTimeFinal = row['OutBedTime']
else:
SleepDate = -1
InBedTimeFinal = -1
OutBedTimeFinal = -1
return SleepDate, InBedTimeFinal, OutBedTimeFinal
s1['SleepDate'], s1['InBedTimeFinal'], s1['OutBedTimeFinal'] = s1.apply(f, axis=1)
I would like to create 3 new columns with apply() but there is
ValueError: too many values to unpack (expected 3)
If I use this, only one column was created with 3 values combined:
s1['SleepDate', 'InBedTimeFinal', 'OutBedTimeFinal'] = s1.apply(f, axis=1)
Could you please help? Thanks.
Upvotes: 0
Views: 817
Reputation: 25259
Your function f
returns tuple for each row, so apply
stacks tuples to series. You need f
return series and unpack on ndarray of the result of apply
def f(row):
if row['CountInBedDate'] == 1 and row['CountOutBedDate'] == 1:
SleepDate = row['DateInBed']
InBedTimeFinal = row['InBedTime']
OutBedTimeFinal = row['OutBedTime']
else:
SleepDate = -1
InBedTimeFinal = -1
OutBedTimeFinal = -1
return pd.Series([SleepDate, InBedTimeFinal, OutBedTimeFinal]) #change here
s1['SleepDate'], s1['InBedTimeFinal'], s1['OutBedTimeFinal'] = s1.apply(f, axis=1).T.values
Upvotes: 1
Reputation: 29635
if f
is your real function, then you should consider using where
instead of apply, it will be way faster.
s1[['SleepDate', 'InBedTimeFinal', 'OutBedTimeFinal']] = \
s1[['DateInBed','InBedTime','OutBedTime']].where(s1['CountInBedDate'].eq(1), other=-1)
Note it seems that in your function you check twice that CountInBedDate is equal to 1
If you want to use apply, then you can try:
s1[['SleepDate', 'InBedTimeFinal', 'OutBedTimeFinal']] = \
pd.DataFrame(s1.apply(f, axis=1).tolist(), s1.index)
Upvotes: 2