How to delete entire row which has empty cell in any column, of a excel sheet containing both texts and numbers - excel

This is my data in excel. How to delete entire row having any empty cell in any column in MATLAB. The sheet contains both texts and numbers,
(col1 col2 col3)
OAS01 0 74
OAS02 0 55
OAS03 0.5 73
OAS04 24
OAS05 21
OAS06 20
OAS07 0 74
OAS08 0 52
OAS09 1 30
OAS01 81
I want to get output like this by deleting of entire and all rows which have any empty cell
(col1 col2 col3)
OAS01 0 74
OAS02 0 55
OAS03 0.5 73
OAS07 0 74
OAS08 0 52
OAS09 1 30
I have tryied but not working well
[num, text, a] = xlsread('data.xlsx');
for i = 1:size(data,1)
if isnan(num(i,1))
a(i,:) =[];
num(i,:) =[];
else
a(i,:) =a(i,:);
num(i,:) =num(i,:);
end
end
xlswrite('newfile.xlsx', a);

Much more elegant way:
T = {'a','b';'','c';'d','e'}
>> T =
'a' 'b'
'' 'c'
'd' 'e'
T(any(cellfun(#isempty,T),2),:) = []
>> T =
'a' 'b'
'd' 'e'
------EDIT-----
OP said it is not working, so I checked, and it is because empty cells gets loaded as NaNs by the xlsread function, so this line should fix it:
[num, text, a] = xlsread('data.xlsx');
a(any(cellfun(#(x) any(isnan(x)),a),2),:) = [];
where a is the 3 by 3 cell that the OP loaded in.
Explanations: cellfun is largely used and well documented, in this particular case, we are interested in setting rows with NaN to [], so we are using matlab's isnan to detect cells which contains NaN, we then wrap the any function outside, which returns a boolean 1 if there is a NaN or a 0 if there isn't a NaN. The outer any generates the boolean index of which (0 is a row with no NaNs and 1 is a row with NaNs) we filter the data on.

Related

selecting different columns each row

I have a dataframe which has 500K rows and 7 columns for days and include start and end day.
I search a value(like equal 0) in range(startDay, endDay)
Such as, for id_1, startDay=1, and endDay=7, so, I should seek a value D1 to D7 columns.
For id_2, startDay=4, and endDay=7, so, I should seek a value D4 to D7 columns.
However, I couldn't seek different column range successfully.
Above-mentioned,
if startDay > endDay, I should see "-999"
else, I need to find first zero (consider the day range) and such as for id_3's, first zero in D2 column(day 2). And starDay of id_3 is 1. And I want to see, 2-1=1 (D2 - StartDay)
if I cannot find 0, I want to see "8"
Here is my data;
data = {
'D1':[0,1,1,0,1,1,0,0,0,1],
'D2':[2,0,0,1,2,2,1,2,0,4],
'D3':[0,0,1,0,1,1,1,0,1,0],
'D4':[3,3,3,1,3,2,3,0,3,3],
'D5':[0,0,3,3,4,0,4,2,3,1],
'D6':[2,1,1,0,3,2,1,2,2,1],
'D7':[2,3,0,0,3,1,3,2,1,3],
'startDay':[1,4,1,1,3,3,2,2,5,2],
'endDay':[7,7,6,7,7,7,2,1,7,6]
}
data_idx = ['id_1','id_2','id_3','id_4','id_5',
'id_6','id_7','id_8','id_9','id_10']
df = pd.DataFrame(data, index=data_idx)
What I want to see;
df_need = pd.DataFrame([0,1,1,0,8,2,8,-999,8,1], index=data_idx)
You can create boolean array to check in each row which 'Dx' column(s) are above 'startDay' and below 'endDay' and the value is equal to 0. For the first two conditions, you can use np.ufunc.outer with the ufunc being np.less_equal and np.greater_equal such as:
import numpy as np
arr_bool = ( np.less_equal.outer(df.startDay, range(1,8)) # which columns Dx is above startDay
& np.greater_equal.outer(df.endDay, range(1,8)) # which columns Dx is under endDay
& (df.filter(regex='D[0-9]').values == 0)) #which value of the columns Dx are 0
Then you can use np.argmax to find the first True per row. By adding 1 and removing 'startDay', you get the values you are looking for. Then you need to look for the other conditions with np.select to replace values by -999 if df.startDay >= df.endDay or 8 if no True in the row of arr_bool such as:
df_need = pd.DataFrame( (np.argmax(arr_bool , axis=1) + 1 - df.startDay).values,
index=data_idx, columns=['need'])
df_need.need= np.select( condlist = [df.startDay >= df.endDay, ~arr_bool.any(axis=1)],
choicelist = [ -999, 8],
default = df_need.need)
print (df_need)
need
id_1 0
id_2 1
id_3 1
id_4 0
id_5 8
id_6 2
id_7 -999
id_8 -999
id_9 8
id_10 1
One note: to get -999 for id_7, I used the condition df.startDay >= df.endDay in np.select and not df.startDay > df.endDay like in your question, but you can cahnge to strict comparison, you get 8 instead of -999 in this case.

Excel 2016 Select lowest figure from a row if cell above matches condition

I need to select lowest value from a row if cell depending on cell above/below so for these two rows:
45 65 98 58 10 32 56 78 65 78 35 49 67 12 54 65
Y N Y Y N Y Y N Y Y N Y Y N Y Y
the answer would be:
Y=32
N=10
I can find it for the whole row of numbers but just don't know how to select or deselect based on the criteria in the other row
Say you have
In B4 you would write
=MIN( IF( $A$2:$P$2=$A4, $A$1:$P$1, "" ) )
And then press Ctrl+Shift+Enter.
Explaination
IF( $A$2:$P$2=$A4, $A$1:$P$1, "" )
reads as: where $A$2:$P$2 is equal to $A4, consider the adjacent value stored in $A$1:$P$1, otherwise consider an empty string.
min( ... )
reads as: take the minimum of the just-considered array.

Excel: Sum columns and rows if criteria is met

I have a sheet with product names in column I and then dates from there on. For each date there are numbers of how many pieces of a certain product have to be made. I'm trying to sum all those numbers based on a product type, i.e.:
I K L M ...
30.8. 31.8. 1.9. ...
MAD23 2 0 45 ...
MMR32 5 7 33 ...
MAD17 17 56 0 ...
MAD: 120 (2+0+45+17+56+0)
MMR: 45 (5+7+33)
What I'm doing now is sum the row first:
=SUM(K6:GN6)
MAD23 = 47
MMR32 = 45
MAD32 = 73
And then sum those numbers in column J based on part of the product name in column I:
=SUMIF(Sheet1!I6:I775;"MAD*";Sheet1!J6:J775)
MAD = 120
MMR = 45
Is it possible to do this with just one formula per criteria?
Just trying it on those three rows, I get
=SUM($K$6:$M$8*(LEFT($I$6:$I$8,LEN(I10)-1)=LEFT(I10,LEN(I10)-1)))
which is an array formula and must be entered with CtrlShiftEnter
That's assuming that I10 is going to contain some characters followed by a colon and you want to match those with the first characters of I6:I8.
=SUM(IF(MID(Sheet1!I6:I775,1,3)="MAD",Sheet1!k6:gn775,""))
With ctrl +shift+enter

Countif after filterlist Excel

I would like to see a working example of how to get this formula properly working
=SUMPRODUCT(SUBTOTAL(3,OFFSET($P$7,ROW($P$8:$P$5500)-ROW($P$7),,1)),--($P$7:$P$5500="74"))
What im trying to achieve is count all the cells within a range that value is greater than
zero, but i need to get that working after i apply a filter. I have seen several examples and havent get it working, with the subtotal fx.
Thanks in advance, for any help!
Working example:
O P
4
5 6
6
7 Filter Data
8 1 74
9 0 74
10 1 74
11 0 74
12 1 74
13 0 74
Formula in P5:
=SUMPRODUCT(SUBTOTAL(103,OFFSET($P$7,ROW($P$8:$P$20)-ROW($P$7),,1)),--($P$8:$P$20=74))
Now you can filter column O and P5 counts only the visible 74.
With function 103 in SUBTOTAL, I really count only the visible cells. This means, also the manually hidden cells are not counted. With function 3 only the out filtered cells are not counted. If cells are manually hidden, they are counted, even if they are not visible.
And I have used the value 74 instead of the text "74". So in my example the column P contains numbers, not text.
How it works:
The formulas within SUMPRODUCT are in array (matrix) context. This means they are handled as if they are used in array formulas.
In array context {ROW($P$8:$P$20)-ROW($P$7)} gets ROW($P$8)-ROW($P$7) = 1, ROW($P$9)-ROW($P$7) = 2, ROW($P$10)-ROW($P$7) = 3 and so on.
OFFSET($P$7,1,,1) will get $P$7+1Row = $P$8, OFFSET($P$7,2,,1) will get $P$7+2Row = $P$9 and so on.
So {OFFSET($P$7,ROW($P$8:$P$20)-ROW($P$7),,1)} gets {$P$8,$P$9,$P$10,...}
Within SUBTOTAL(103, {$P$8,$P$9,$P$10,...}) it counts 1 if {$P$8,$P$9,$P$10,...} is visible and 0 if not.
So the SUMPRODUCT results in
SUMPRODUCT({1,0,1,0,1,0,0,...}, --($P$8:$P$20=74))
The {($P$8:$P$20=74)} results in {TRUE,TRUE,TRUE,FALSE,TRUE,...} depend of if $P$8:$P$20=74. The -- (*-1*-1) gets this in numeric context, so that the TRUE = 1 and FALSE = 0.
So the SUMPRODUCT finally results in
SUMPRODUCT({1,0,1,0,1,0,0,...}, {1,1,1,1,1,1,0,...})
Greetings
Axel

Find what range a number belongs to

Ive written a function to calculate what MARK a student gets, based on a scoring table.
Why does my function work only for A mark?
This what the excel sheet looks like
COLUMN: A B C
Student SCORE MARK
1 adsf 90 A
2 asgfd 89 FALSE
3 A 90 100
4 B 81 89
5 C 71 80
6 D 61 70
7 E 56 60
8 Fx 0 55
This is the function:
{=IF(B1>=$B$3:$B$8,IF(B1<=$C$3:$C$8,$A$3:$A$8))}
I'm using {} brackets for array functions. (CTRL SHIFT ENTER)
Thank you
You're on the right track but your formula is returning an array not a single value. Wrapping the result in LOOKUP should give the desired result:
=LOOKUP("Z",IF(B1>=$B$3:$B$8,IF(B1<=$C$3:$C$8,$A$3:$A$8))
This returns the last matching grade since "Z" is larger than any other text value in the range.
A simpler method is:
=LOOKUP(-B1,-C$3:C$8,A$3:A$8)
The negative signs are needed so that the lookup values are in ascending order.

Resources