Reputation: 47
I am attempting to create a new column called ['FirstYearSales'] which takes the values in the ['CohortYear'] column and looks up the corresponding column label and provide the corresponding value in the row. Does anyone know how to accomplish this?
data = [[2017, 150, 200, 300], [2018, 0, 750, 650], [2019, 0, 0, 50]]
data = pd.DataFrame(data, columns = ['CohortYear', '2017', '2018', '2019'])
CohortYear 2017 2018 2019
0 2017 150 200 300
1 2018 0 750 650
2 2019 0 0 50
The desired results would look something like this:
CohortYear FirstYearSales 2017 2018 2019
0 2017 150 150 200 300
1 2018 750 0 750 650
2 2019 50 0 0 50
One of my failed attempts:
data['FirstYearSales'] = data.loc[list(data.columns.values)] == ['CohortYear']
Upvotes: 1
Views: 45
Reputation: 75100
Try lookup
with insert
(for inserting column after 'CohortYear' column) after getting position from get_loc
:
val = data.lookup(data.index,data['CohortYear'].map(str))
data.insert(data.columns.get_loc("CohortYear")+1,"FirstYearSales",val)
print(data)
CohortYear FirstYearSales 2017 2018 2019
0 2017 150 150 200 300
1 2018 750 0 750 650
2 2019 50 0 0 50
Lookup seems to be faster avoid apply
on axis=1
as it is likely to be slow: (sample run against 30K rows):
m = pd.concat([data]*10000,ignore_index=True)
%%timeit
m.lookup(m.index,m['CohortYear'].map(str))
#23.7 ms ± 805 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
m
%%timeit
m.apply(lambda x: x[str(x.CohortYear)], axis=1)
#1.98 s ± 70.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Upvotes: 1
Reputation: 1560
Using pd.DataFrame.apply
:
data['FirstYearSales'] = data.apply(lambda x: x[str(x.CohortYear)], axis=1)
CohortYear 2017 2018 2019 FirstYearSales
0 2017 150 200 300 150
1 2018 0 750 650 750
2 2019 0 0 50 50
Upvotes: 2