I have a dataframe.Structure:
SEQ product_name prod_cost non-prd_cost mgmt grand_total
1 prod1 100 200 20 320
2 prod2 200 400 30 630
3 prod3 300 500 40 840
4 prod4 100 300 50 450
I want to calculate sumproduct(in excel) based on condition.The condition is based on product_name.
lets say I want to calculate a variable called
sumprod_prod1_prd_prod3_mgmt = SUMPRODUCT(SEQ 1-4,product_name='prod1'_prod_cost and 'prod3'_mgmt)/2 = 100+40=140
How can I do this in pandas?
While I am a bit confused by your question, since the excel SUMPRODUCT function returns the sum of the products of corresponding ranges or arrays, and you seem to want the SUM of a singular combination.
To get the desired value:
sumprod_prod1_prd_prod3_mgmt = df[df['product_name'] == 'prod1']['prod_cost'].values[0]+df[df['prod_name']=='prod3']['mgmt'].values[0]
This solution gives a single result for the specified values. If you need a solution which provides the same functionality as excel, please update your question and example to better define what you are looking for.
Related
I need to create a logic excel formula that calculates the average of 3 months prior to a specified start date. There are multiple start dates. For instance:
For ID 1, The Start Date is May-2021. I would need for the logic to calculate the average between Feb-2021 to Apr-2021 to get 91.67. For ID 2, the Start Date is Jun-2021, so I would need to calculate the average of Mar-2021 to May 2021 to get 108.33. I also would need to calculate the average of 6 months prior in a separate column.
ID
Start Date
Calculation Result
Jan-2021
Feb-2021
Mar-2021
Apr-2021
May-2021
Jun-2021
1
May-2021
91.67
50
100
75
100
25
0
2
Jun-2021
108.33
0
25
100
175
50
125
3
Apr-2021
83.33
100
150
0
75
0
200
Any help is greatly appreciated! (Not opposed to VBA suggestions either)
use INDEX to create the range.
=AVERAGE(INDEX(D2:I2,MATCH(B2,$D$1:$I$1,0)-3):INDEX(D2:I2,MATCH(B2,$D$1:$I$1,0)-1))
Or if they are true dates we can use AverageIfs:
=AVERAGEIFS(D2:I2,$D$1:$I$1,">"&EOMONTH(B2,-4),$D$1:$I$1,"<="&EOMONTH(B2,-1))
I have data in Excel in the following format:
Column A Column B
20/03/2018 300
21/03/2018 200
22/03/2018 100
23/03/2018 90
24/03/2018 300
25/03/2018 200
26/03/2018 100
27/03/2018 50
28/03/2018 90
29/03/2018 100
30/03/2018 110
31/03/2018 120
I would like to get the date where the minimum of B would never be under 99 again chronologically. It the example above, that would happen the 29th of March.
If I try to get it with: =INDEX(A:A,MATCH(99,B1:B12,-1)) the value returned is 22/03/2018 as it is the first occurrence found, searched from top to bottom.
In this case it would be perfect to be able to do a reverse match(e.g. a match that searches from bottom to top of the range) but this option is not available. I have seen that it is possible to do reverse matches with the lookup function but in that case I need to provide a value that is actually in my data set (99 would not work).
The workaround I have found is to add a third column like the following (with the minimum of the upcoming value of B going down) and index match on top it.
Column A Column B Column C
20/03/2018 300 50
21/03/2018 200 50
22/03/2018 100 50
23/03/2018 90 50
24/03/2018 300 50
25/03/2018 200 50
26/03/2018 100 50
27/03/2018 50 50
28/03/2018 90 90
29/03/2018 100 100
30/03/2018 110 110
31/03/2018 120 120
Is there a way of achieving this without a third column?
The AGGREGATE function is great for problems like these:
=AGGREGATE(14,4,(B2:B13<99)*A2:A13,1)+1
What are those numeric arguments?
14 tells the function to replicate a LARGE function
4 to ignore no values (this function can ignore error values and other things)
More info here. I checked it works below:
If your dates aren't always consecutive, you'll need to add a bit more to the function:
=INDEX(A1:A12,MATCH(AGGREGATE(14,6,(B1:B12<99)*A1:A12,1),A1:A12,0)+1)
=INDEX(A1:A12,LARGE(IF(B1:B12<=99,ROW(B1:B12)+1),1))
This is an array formula (Ctrl+Shift+Enter while still in the formula bar)
Builds an array of the row 1 below results that are less than or equal to 99. Large then returns the largest row number for index.
I have a column with ordinal values. I want to have another column that ranks them in equal groups (relatively to their value).
Example: If I have a score and I want to divide to 5 equal groups:
Score
100
90
80
70
60
50
40
30
20
10
What function do I use in the new column to get this eventually:
Score Group
100 5
90 5
80 4
70 4
60 3
50 3
40 2
30 2
20 1
10 1
Thanks! (I'm guessing the solution is somewhere in mod, row and count - but I couldn't find any good solution for this specific problem)
If you don't care about how the groups are split for groups that aren't evenly divisible, you can use this formula and drag down as far as necessary:
= FLOOR(5*(COUNTA(A:A)-COUNTA(INDEX(A:A,1):INDEX(A:A,ROW())))/COUNTA(A:A),1)+1
Possibly a more efficient solution exists, but this is the first way I thought to do it.
Obviously you'll have to change the references to the A column if you want it in a different column.
See below for working example.
I have a few hundred rows of data, and each has a number between 1 and 200, and I'd like to put them in categories of 1-5 depending on where that number is.
The categories look like this:
Zones Min Max
1 0 35
2 35 60
3 60 85
4 85 110
5 110 200
I want to assign it a Zone if it is greater than the Min, but less than the Max.
I have 2 formulas I've been working with to solve it. One is a nested IF AND statement:
=IF(A1<=35,1,IF(AND(A1<=60,A1>35),2,IF(AND(A1<=85,A1>60),3,IF(AND(A1<=110,A1>85),4,IF(AND(A1<=200,A1>110),2,"TOO BIG")))))
The 2nd formula attempts to use a SUMPRODUCT function:
=INDEX($C$2:$C$6,SUMPRODUCT(--(A1<=$E$2:$E$6),-- (A1>$D2:$D$6),ROW($2:$6)))
Rather than have to continue to adjust the numeric values manually, I set them as absolutes, which is why this formula is slightly different. The E column is the Max value set, and the D is the Min value set.
Any help would be appreciated!
Use this:
=MATCH(A1,{0,35,60,85,110})
Another way is to use VLOOKUP and you just need to set the min number:
=VLOOKUP(D2,$A$2:$B$6,2,1)
The key is the 4th parameter needs to set to 1 which means TRUE. It will find the closest value and return the zone for you.
But noticed that you have overlaps like 35 or 60 etc. that you will need to adjust your value column.
I have a data set something like this
Units Price
1 15
100 10
150 9
200 8
50000 7
I need the output as Price with respect to quantity.
Example- If Input value is 90 it should give price as 15
If input is 210 it should give value as 8.
However,sadly I cannot use IF statement.
Thanks in advance.
You can use a combination of INDEX and MATCH
=INDEX(B1:B5,MATCH(lookup_value,A1:A5,1))
This assumes Units are in column A and Price is in column B
Make sure you understand both functions:
INDEX
MATCH - particularly the reason for the ,1) at the end
You can also use VLOOKUP. This is probably a bit easier although INDEX/MATCH is more versatile:-
=VLOOKUP(Lookup_value,$A$2:$B$6,2,TRUE)