Combining elements within a 2d array python 3.x - arrays

i have this 2d array, where each array is made up of 4 lots of 4 hex values:
list1=[['74 68 61 74', '73 20 6D 79', '20 6B 75 6E', '67 20 66 75'], ['C2 5B FC F1', 'B1 7B 91 88', '91 10 E4 E6', 'F6 30 82 93']]
And I would like to firstly split the array into multiple 1d arrays then combine the array into multiple single elements rather than each element having 4 values, like follows:
list2=[74, 68, 61, 74, 73, 20, 6D, 79, 20, 6B, 75, 6E, 67, 20, 66, 75]
list 3=[C2, 5B, FC, F1, B1, 7B, 91, 88, 91, 10, E4, E6, F6, 30, 82, 93]
Please let me know how this can be done. Thank you in advance.

What you essentially want to do is "flatten" the inner lists. There are several approaches to this. The example below borrows from here. Realize that the values in your lists are just strings (even though they could represent hex values) so you need to treat them like strings when splitting them up.
In [25]: list1
Out[25]:
[['74 68 61 74', '73 20 6D 79', '20 6B 75 6E', '67 20 66 75'],
['C2 5B FC F1', 'B1 7B 91 88', '91 10 E4 E6', 'F6 30 82 93']]
In [26]: list2 = [t for sublist in list1[0] for t in sublist.split(' ')]
In [27]: list3 = [t for sublist in list1[1] for t in sublist.split(' ')]
In [28]: list2
Out[28]:
['74',
'68',
'61',
'74',
'73',
'20',
'6D',
'79',
'20',
'6B',
'75',
'6E',
'67',
'20',
'66',
'75']
In [29]: list3
Out[29]:
['C2',
'5B',
'FC',
'F1',
'B1',
'7B',
'91',
'88',
'91',
'10',
'E4',
'E6',
'F6',
'30',
'82',
'93']
In [30]:

Related

Find increasing and decreasing values in a column SNOWFLAKE ,SQL

I have a table in snowflake like below, and wanted to add new column represents if that row is increasing or decreasing based on the next row!
id
value
1
70
2
70
3
70
4
70
5
70
6
71
7
72
8
73
9
73
10
73
11
74
12
74
13
74
14
74
15
73
16
72
17
73
18
72
19
72
20
72
21
72
22
71
23
71
24
72
25
72
Expected Output:
id
value
DESIRED OUTPUT
1
70
INCREASING_ID1
2
70
INCREASING_ID2
3
70
INCREASING_ID3
4
70
INCREASING_ID4
5
70
INCREASING_ID5
6
71
INCREASING_ID6
7
72
INCREASING_ID7
8
73
INCREASING_ID8
9
73
INCREASING_ID9
10
73
INCREASING_ID10
11
74
INCREASING_ID11
12
74
INCREASING_ID12
13
74
INCREASING_ID13
14
74
INCREASING_ID14
15
73
DECREASING_ID15
16
72
DECREASING_ID16
17
73
INCREASING_ID17
18
72
DECREASING_ID18
19
72
DECREASING_ID19
20
72
DECREASING_ID20
21
72
DECREASING_ID21
22
71
DECREASING_ID22
23
71
DECREASING_ID23
24
72
INCREASING_ID24
25
72
INCREASING_ID25
This is a two step process. First step, find the direction of the lag: increasing, decreasing, or null if neither direction. Second step, if the current direction for a row is null, refer back to the last non-null value (null previously defined as no change in direction):
with DIRECTION as
(
select ID
,VALUE
,case
when ID = 1 then 'INCREASING'
when VALUE > lag(VALUE) over (order by id) then 'INCREASING'
when VALUE < lag(VALUE) over (order by id) then 'DECREASING'
else NULL
end as OUTPUT
from T1
)
select ID
,VALUE
,case when OUTPUT is null then
lag(OUTPUT) ignore nulls over (order by ID) || '_ID' || ID
else OUTPUT || '_ID' || ID
end as OUTPUT
from DIRECTION
;
So this is the same answer is Greg's, I have just written it verbosely to show the workings:
firstly a CTE for data:
with data(id, value, DESIRED_OUTPUT) as (
select * from values
(1, 70, 'INCREASING_ID1'),
(2, 70, 'INCREASING_ID2'),
(3, 70, 'INCREASING_ID3'),
(4, 70, 'INCREASING_ID4'),
(5, 70, 'INCREASING_ID5'),
(6, 71, 'INCREASING_ID6'),
(7, 72, 'INCREASING_ID7'),
(8, 73, 'INCREASING_ID8'),
(9, 73, 'INCREASING_ID9'),
(10, 73, 'INCREASING_ID10'),
(11, 74, 'INCREASING_ID11'),
(12, 74, 'INCREASING_ID12'),
(13, 74, 'INCREASING_ID13'),
(14, 74, 'INCREASING_ID14'),
(15, 73, 'DECREASING_ID15'),
(16, 72, 'DECREASING_ID16'),
(17, 73, 'INCREASING_ID17'),
(18, 72, 'DECREASING_ID18'),
(19, 72, 'DECREASING_ID19'),
(20, 72, 'DECREASING_ID20'),
(21, 72, 'DECREASING_ID21'),
(22, 71, 'DECREASING_ID22'),
(23, 71, 'DECREASING_ID23'),
(24, 72, 'INCREASING_ID24'),
(25, 72, 'INCREASING_ID25')
)
then two selects, as the two LAG's cannot co-exist at the same level:
select *
,lag(change)ignore nulls over(order by id) as lag_change
,nvl(change, lag_change) || '_ID' || id as final_answer
,DESIRED_OUTPUT = final_answer as is_same
from (
select *
,lag(value)over(order by id) as lag_v
,case
when lag_v is null then 'INCREASING'
when value<lag_v then 'DECREASING'
when value>lag_v then 'INCREASING'
end as change
from data
)
order by 1;
ID
VALUE
DESIRED_OUTPUT
LAG_V
CHANGE
LAG_CHANGE
FINAL_ANSWER
IS_SAME
1
70
INCREASING_ID1
null
INCREASING
null
INCREASING_ID1
TRUE
2
70
INCREASING_ID2
70
null
INCREASING
INCREASING_ID2
TRUE
3
70
INCREASING_ID3
70
null
INCREASING
INCREASING_ID3
TRUE
4
70
INCREASING_ID4
70
null
INCREASING
INCREASING_ID4
TRUE
5
70
INCREASING_ID5
70
null
INCREASING
INCREASING_ID5
TRUE
6
71
INCREASING_ID6
70
INCREASING
INCREASING
INCREASING_ID6
TRUE
7
72
INCREASING_ID7
71
INCREASING
INCREASING
INCREASING_ID7
TRUE
8
73
INCREASING_ID8
72
INCREASING
INCREASING
INCREASING_ID8
TRUE
9
73
INCREASING_ID9
73
null
INCREASING
INCREASING_ID9
TRUE
10
73
INCREASING_ID10
73
null
INCREASING
INCREASING_ID10
TRUE
11
74
INCREASING_ID11
73
INCREASING
INCREASING
INCREASING_ID11
TRUE
12
74
INCREASING_ID12
74
null
INCREASING
INCREASING_ID12
TRUE
13
74
INCREASING_ID13
74
null
INCREASING
INCREASING_ID13
TRUE
14
74
INCREASING_ID14
74
null
INCREASING
INCREASING_ID14
TRUE
15
73
DECREASING_ID15
74
DECREASING
INCREASING
DECREASING_ID15
TRUE
16
72
DECREASING_ID16
73
DECREASING
DECREASING
DECREASING_ID16
TRUE
17
73
INCREASING_ID17
72
INCREASING
DECREASING
INCREASING_ID17
TRUE
18
72
DECREASING_ID18
73
DECREASING
INCREASING
DECREASING_ID18
TRUE
19
72
DECREASING_ID19
72
null
DECREASING
DECREASING_ID19
TRUE
20
72
DECREASING_ID20
72
null
DECREASING
DECREASING_ID20
TRUE
21
72
DECREASING_ID21
72
null
DECREASING
DECREASING_ID21
TRUE
22
71
DECREASING_ID22
72
DECREASING
DECREASING
DECREASING_ID22
TRUE
23
71
DECREASING_ID23
71
null
DECREASING
DECREASING_ID23
TRUE
24
72
INCREASING_ID24
71
INCREASING
DECREASING
INCREASING_ID24
TRUE
25
72
INCREASING_ID25
72
null
INCREASING
INCREASING_ID25
TRUE
and thus the final SQL can be:
select id, value
,nvl(change, lag(change)ignore nulls over(order by id)) || '_ID' || id as final_answer
from (
select id, value
,lag(value)over(order by id) as lag_v
,case
when lag_v is null then 'INCREASING'
when value<lag_v then 'DECREASING'
when value>lag_v then 'INCREASING'
end as change
from data
)
order by 1;
which is the same as Greg's other than I have used the implicit NULL result in the inner CASE, and I used a NVL instead of CASE in the outer SELECT, a COALESCE could also be used here.

Create JSON Array with values from table

i like to create an array and call the values. I stuck # starting :(
My Table (static)
Level | RPM 20 30 40 50 60 70 80 90 100 110 120 130
------------------------------------------------------
6 | 15 31 52 75 105 135 166 202 231 275 289
7 | 16 35 58 85 118 152 185 226 260 305 332
8 | 18 39 65 96 131 169 208 249 289 333 375
for example: # Level 6 and RPM >60<70 = 135
# Level 7 and RPM >50<60 = 118
And the bigger idea, can i interpolate between values so when i for example #65 RPM have the right values?
Is a array the right choice for this? How to build this array?
I find no example for this.
Is this the right way?
{
{
"Level6": "RPM20",
"Watt": 15,
}
{
"Level6": "RPM30",
"Watt": 31,
}
}
But in this way i type like hell!?
This is more interesting:
[
{
"Level X RPM": 6,
"20": 15,
"30": 31,
"40": 52,
"50": 69,
"60": 89,
"70": 106,
"80": 125,
"90": 143
},
{
"Level X RPM": 7,
"20": 16,
"30": 35,
"40": 52,
"50": 70,
"60": 88,
"70": 107,
"80": 124,
"90": 142
},
{
"Level X RPM": 8,
"20": 18,
"30": 39,
"40": 65,
"50": 87,
"60": 111,
"70": 135,
"80": 158,
"90": 180
}
]
I have changed and my List is now Python:
LEVEL_TO_POWER = {
1: [6,12,20,29,40,53,69,79,92,106,121],
2: [8,16,26,38,53,68,88,103,120,138,152],
3: [9,20,32,47,66,84,107,125,148,172,186],
4: [11,23,39,56,79,101,126,150,173,206,219],
5: [13,27,45,65,92,117,145,175,202,238,254],
6: [15,31,52,75,105,135,166,202,231,275,289],
7: [16,35,58,85,118,152,185,226,260,305,332],
8: [18,39,65,96,131,169,208,249,289,333,375],
9: [19,42,71,104,144,184,227,272,318,361,408],
10:[21,46,77,113,157,199,245,295,345,386,442],
11:[23,50,84,123,170,216,262,318,372,413,480],
12:[24,53,89,131,183,230,279,342,398,441,512],
13:[26,56,94,139,196,245,296,365,424,468,548],
14:[28,60,101,148,209,261,318,389,449,494,585],
15:[30,64,108,158,222,277,337,415,476,518,620],
16:[32,68,115,168,235,296,355,439,503,548,658],
17:[33,72,122,177,248,312,373,463,530,576,694],
18:[35,76,129,187,261,328,390,484,556,606,727],
19:[37,79,134,195,274,342,407,507,572,632,763],
20:[39,83,140,204,287,354,424,528,598,659,790],
21:[40,87,146,213,300,368,442,551,616,689,812],
22:[42,91,153,223,313,385,461,574,645,720,840],
23:[44,95,160,234,326,401,479,598,673,752,872],
24:[47,101,171,246,340,418,501,625,706,788,908],
}

add each column to array, not just whole line - PERL

I am writing a perl script and currently working on a subroutine to sum all values of an array. Currently, my code only reads in each line and stores the entire line into each array element. I need each individual number stored in it's own element.
Here's a sample of my data:
50 71 55 93 115
45 76 49 88 102
59 78 53 96 145
33 65 39 82 100
54 77 56 98 158
Here's my code:
my #array;
#bring in each line and store into array called 'array'
open(my $fh, "<", "score")
or die "Failed to open file: $!\n";
while(<$fh>) {
chomp;
push #array, $_;
}
close $fh;
When I call my subroutine to sum the values of the array, my result is 241. That is the sum of each of the first numbers in each line.
Any help or suggestions?
So, you want to add all values inside an array. Easy, But In your code, you are adding strings of values instead of value itself.
With push #array, $_; you are creating an array of lines in the file score.
Try:
print Dumper(\#array);
You will see output like this:
$VAR1 = [
'50 71 55 93 115',
'45 76 49 88 102',
'59 78 53 96 145',
'33 65 39 82 100',
'54 77 56 98 158'
];
So when you are adding the values, it adds all elements of array:
'50 71 55 93 115' + '59 78 53 96 145' + '33 65 39 82 100' ......and so on
The moment you put + with string it is treated as numeric and by default, perl adds first character in the string to the first character in the other string. If the first character is not a number, It is treated as 0.
You should check perlop for more info.
The solution for this problem is to separate the numbers from every line, treat each of them individually and store them inside the array. This can be done simply using:
push #array, split;
Now when you try:
print Dumper(\#array);
It will be like this:
$VAR1 = [
'50',
'71',
'55',
'93',
'115',
'45',
'76',
'49',
'88',
'102',
'59',
'78',
'53',
'96',
'145',
'33',
'65',
'39',
'82',
'100',
'54',
'77',
'56',
'98',
'158'
];
After this just call your subroutine using:
my $total_sum = sum(#array);
print $total_sum,"\n";
and define your subroutine as:
sub sum {
my #nums = #_;
my $total_sum = 0;
$total_sum += $_ foreach(#nums);
return $total_sum;
}
The output will be 1937 as expected.

Create 3-dimensional array from 2 dimensional array in matlab

I would like to know how to generate a 3-d array from a 2-d array in matlab. My lack of understanding may simply be the result of not knowing the correct nomenclature.
I have a 2-dimensional array or matrix, A:
A = [12, 62, 93, -8, 22; 16, 2, 87, 43, 91; -4, 17, -72, 95, 6]
and I would like to add a 3rd dimension with the same values such that:
A(:,:,1) = 12 62 93 -8 22
16 2 87 43 91
-4 17 -72 95 6
and
A(:,:,2) = 12 62 93 -8 22
16 2 87 43 91
-4 17 -72 95 6
to
A(:,:,p) = 12 62 93 -8 22
16 2 87 43 91
-4 17 -72 95 6
how would I go about doing so in the most efficient way (I might have a much larger array where m = 100, n = 50, p= 1000 where A(m,n,p).
Try
result = reshape(repmat(A,1,p),m,n,p)

Ordering array according to index ~ text

Please, put in R these datas:
S.names <- c("FXI", "XLB", "GLD", "IWM", "XLE", "XLF", "EWZ", "GDX", "XLK",
"TLT", "IYR", "QQQ", "SLV", "EWJ", "XLV", "DIA", "XHB", "EEM",
"USO", "VWO", "SPY", "EFA")
strike_vec <- structure(list(Strike = c(152, 43, 61, 11, 56, 37, 36, 159, 96,
74, 71, 27, 163, 128, 35, 44, 30, 40, 81, 19, 31, 48)), .Names = "Strike", row.names =
c("DIA", "EEM", "EFA", "EWJ", "EWZ", "FXI", "GDX", "GLD", "IWM", "IYR",
"QQQ", "SLV", "SPY", "TLT", "USO", "VWO", "XHB", "XLB", "XLE",
"XLF", "XLK", "XLV"), class = "data.frame")
As you can see, strike_vec row names are equal to S.names elements.
I would like to order strike_vec elements according to the order of S.names, that is associating each strike_vec element to the position in which you find the corresponding S.names row name.
The final result should be something like
> strike_vec.new
[,1]
FXI 37
XLB 40
GLD 159
IWM 96
...
...
...
where rownames(strike_vec.new) follows exactly the order of S.names.
How may I do?
Just use :
strike_vec[S.names,,drop=FALSE]
Which gives :
Strike
FXI 37
XLB 40
GLD 159
IWM 96
XLE 81
XLF 19
EWZ 56
GDX 36
XLK 31
TLT 128
IYR 74
QQQ 71
SLV 27
EWJ 11
XLV 48
DIA 152
XHB 30
EEM 43
USO 35
VWO 44
SPY 163
EFA 61
This works because if you index the rows of a data frame with a character vector, indexing will be based on row names.

Resources