I want to export my Data in a Cell Array to an Excel file, as tidy as possible, without semi-colons for new rows - excel

I have a Cell Array of dimensions 2 by 40, and each cell contains a matrix of dimensions 3 by 3:
[3x3 double] [3x3 double] [3x3 double] ... [3x3 double]
[3x3 double] [3x3 double] [3x3 double] ... [3x3 double]
Now, I need to print this Cell Array and show it to my study group. Below is the detailed example of what I am trying to achieve.
Print should show each matrix in the cell clearly and separately, so that we can study it better, similar to this:
[1 2 3] [5 2 3]
[4 5 6] [1 2 2] ...
[7 8 9] [7 8 9]
[5 2 3] [4 5 6]
[3 5 6] [7 2 9] ...
[7 1 9] [5 2 3]
I tried converting Cell to Table, unfortunately this was untidy, as it showed each new row of matrices with semi-colons:
[1 2 3; 4 5 6; 7 8 9]
Also, I tried converting Cell to Double with:
data = [cell{1,:};cell{2,:}];
resulting in 6 by 120 double, looking like this:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
I can export this to an Excel file, however you can see that it is still cumbersome. I can cut and paste the rows 4,5,6 and shift them below so that it looks like:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
however I still need to divide every other 3 columns, so that I can achieve what I want, which is very impractical:
1 2 3 5 2 3
4 5 6 1 2 2 ...
7 8 9 7 8 9
5 2 3 2 5 6
3 5 6 7 2 9 ...
7 1 9 5 2 3
I would really appreciate your help on this one. Thank you in advance.

To display a complex cell array like this, you can use celldisp to display the cell in an understandable way.
% Create some example data
D = arrayfun(#(x)rand(3,3), ones(2,2), 'uni', 0);
% Display it
celldisp(D)
Another possible way to display this is to create a custom little routine to print the data.
formatspec = '%10.4f';
format = repmat([repmat([formatspec ' '], [1 size(D{1},2)]), ' '], [1 size(D,2)]);
arrayfun(#(k)fprintf('%s\n', sprintf([format, '\n'], cat(2, D{k,:}).')), 1:size(D,1))
A third option, if you really want to export to Excel, you will want to alter the fprintf statement to create a CSV file.
fid = fopen('data.csv', 'w');
% Create the format specifier for a row
format = repmat([repmat('%0.4f,', [1 size(D{1}, 2)]), ','], [1 size(D,2)]);
format(end-1:end) = '';
for k = 1:size(D, 1)
fprintf(fid, [format '\n'], cat(2, D{k,:}).');
% Create an empty row
fprintf(fid, ',\n');
end
fclose(fid);
The result when loaded in Excel.

Related

How to generate an nd-array where values are greater than 1? [duplicate]

This question already has answers here:
Generate random array of floats between a range
(10 answers)
Closed 2 years ago.
Is it possible to generate random numbers in an nd-array such the elements in the array are between 1 and 2 (The interval should be between 1 and some number greater than 1 )? This is what I did.
input_array = np.random.rand(3,10,10)
But the values in the nd-array are between 0 and 1.
Please let me know if that is possible. Any help and suggestions will be highly appreciated.
You can try scaling:
min_val, max_val = 1, 2
input_array = np.random.rand(3,10,10) * (mal_val-min_val) + min_val
or use uniform:
input_array = np.random.uniform(min_val, max_val, (3,10,10))
You can use np.random.randInt() in order to generate nd array with random integers
import numpy as np
rand_arr=np.random.randint(low = 1, high = 10, size = (10,10))
print(rand_arr)
# It changes randomly
#Output:
[[6 9 3 4 9 2 6 2 9 7]
[7 1 7 1 6 2 4 1 8 6]
[9 5 8 3 5 9 9 7 8 4]
[7 3 6 9 9 4 7 2 8 5]
[7 7 7 4 6 6 6 7 2 5]
[3 3 8 5 8 3 4 5 4 3]
[7 8 9 3 5 8 3 5 7 9]
[3 9 7 1 3 6 3 1 4 6]
[2 9 3 9 3 6 8 2 4 8]
[6 3 9 4 9 5 5 6 3 7]]

Confused about numpy array operations

How come this be right?
X=np.array([range(1,12)])
A=X>4
B=X<10
C=(X>4) | (X<10)
print (X[A])
print (X[B])
print (X[C])
[ 5 6 7 8 9 10 11]
[1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10 11]
I'm going to guess that your concern is because you have every element in the final expression, simply because the first two are obvious (5..11 are all greater than four and 1..9 are all less than ten).
But the third one is also right since every element is either greater than four or less than ten. The numbers 1..9 are all less than ten so they're in. Similarly, 5..11 are all greater than four so they're in as well. The union of those two ranges is the entire set of values.
If you wanted the items that were between four and ten (exclusive at both ends), you should probably have used "and" instead of "or" (& instead of |):
import numpy as np
X=np.array([range(1,12)])
A=X>4
B=X<10
C=(X>4) | (X<10)
D=(X>4) & (X<10)
E=(X<=4) | (X>=10)
print (X[A])
print (X[B])
print (X[C])
print (X[D])
print (X[E])
The output of that is:
[ 5 6 7 8 9 10 11]
[1 2 3 4 5 6 7 8 9]
[ 1 2 3 4 5 6 7 8 9 10 11]
[5 6 7 8 9]
[ 1 2 3 4 10 11]
Because you didn't specify what you wanted in the original question), I've also added the opposite operation (to get values not in that range). That's indicated by the E code.

pd.Series(pred).value_counts() how to get the first column in dataframe?

I apply pd.Series(pred).value_counts() and get this output:
0 2084
-1 15
1 13
3 10
4 7
6 4
11 3
8 3
2 3
9 2
7 2
5 2
10 2
dtype: int64
When I create a list I get only the second column:
c_list=list(pd.Series(pred).value_counts()), Out:
[2084, 15, 13, 10, 7, 4, 3, 3, 3, 2, 2, 2, 2]
How do I get ultimately a dataframe that looks like this including a new column for size% of total size?
df=
[class , size ,relative_size]
0 2084 , x%
-1 15 , y%
1 13 , etc.
3 10
4 7
6 4
11 3
8 3
2 3
9 2
7 2
5 2
10 2
You are very nearly there. Typing this in the blind as you didn't provide a sample input:
df = pd.Series(pred).value_counts().to_frame().reset_index()
df.columns = ['class', 'size']
df['relative_size'] = df['size'] / df['size'].sum()

How can i calculate population in pandas?

I have a data set like this:-
S.No.,Year of birth,year of death
1, 1, 5
2, 3, 6
3, 2, -
4, 5, 7
I need to calculate population on till that years let say:-
year,population
1 1
2 2
3 3
4 3
5 4
6 3
7 2
8 1
How can i solve it in pandas?
Since i am not good in pandas.
Any help would be appreciate.
First is necessary choose maximum year of year of death if not exist, in solution is used 8.
Then convert values of year of death to numeric and replace missing values by this year. In first solution is used difference between birth and death column with Index.repeat with GroupBy.cumcount, for count is used Series.value_counts:
#if need working with years
#today_year = pd.to_datetime('now').year
today_year = 8
df['year of death'] = pd.to_numeric(df['year of death'], errors='coerce').fillna(today_year)
df = df.loc[df.index.repeat(df['year of death'].add(1).sub(df['Year of birth']).astype(int))]
df['Year of birth'] += df.groupby(level=0).cumcount()
df1 = (df['Year of birth'].value_counts()
.sort_index()
.rename_axis('year')
.reset_index(name='population'))
print (df1)
year population
0 1 1
1 2 2
2 3 3
3 4 3
4 5 4
5 6 3
6 7 2
7 8 1
Another solution use list comprehension with range for repeat years:
#if need working with years
#today_year = pd.to_datetime('now').year
today_year = 8
s = pd.to_numeric(df['year of death'], errors='coerce').fillna(today_year)
L = [x for s, e in zip(df['Year of birth'], s) for x in range(s, e + 1)]
df1 = (pd.Series(L).value_counts()
.sort_index()
.rename_axis('year')
.reset_index(name='population'))
print (df1)
year population
0 1 1
1 2 2
2 3 3
3 4 3
4 5 4
5 6 3
6 7 2
7 8 1
Similar like before, only is used Counter for dictionary for final DataFrame:
from collections import Counter
#if need working with years
#today_year = pd.to_datetime('now').year
today_year = 8
s = pd.to_numeric(df['year of death'], errors='coerce').fillna(today_year)
d = Counter([x for s, e in zip(df['Year of birth'], s) for x in range(s, e + 1)])
print (d)
Counter({5: 4, 3: 3, 4: 3, 6: 3, 2: 2, 7: 2, 1: 1, 8: 1})
df1 = pd.DataFrame({'year':list(d.keys()),
'population':list(d.values())})
print (df1)
year population
0 1 1
1 2 2
2 3 3
3 4 3
4 5 4
5 6 3
6 7 2
7 8 1

How change an arbitrary range of values to ranged values?

I am going to convert an array as [1 2 6 12 13 15 20 8 30 31] to range [1 2 3 4 5 6 7 8 9 10] in EXCEL or in MATLAB. Is there any function to do it? Is there any suggestion to convert this type of arbitrary range to definite range?
Solution for MATLAB
In MATLAB, unique can do the trick. For example:
A = [1 1 1 1 4 4 5 3 3 6 6 6 6 8]
[C, ia, ic] = unique(A);
Now ic holds the values that you're looking for:
ic =
1 1 1 1 3 3 4 2 2 5 5 5 5 6
Also, you can remap ic to a new order if you wish to do so. For instance, here's a new order similar to the one you suggested:
new_order = [1 3 2 4 6 5];
ic_new = new_order(ic);
which yields:
ic_new =
1 1 1 1 2 2 4 3 3 6 6 6 6 5
Hope that helps!
In Matlab:
v = [1 2 6 12 13 15 20 8 30 31];
v_index = 1:length(v);

Resources