how to multiply nested list with list? - python-3.x

i have:
dataA=[[1,2,3],[1,2,5]]
dataB=[1,2]
I want to multiply index [0] dataA with index [0] dataB, and index [1] dataA with index [1] dataB, how to do it.
I tried it, but the results didn't match expectations
dataA=[[1,2,3],[1,2,5]]
dataB=[1,2]
tmp=[]
for a in dataA:
tampung = []
for b in a:
cou=0
hasil = b*dataB[cou]
tampung.append(hasil)
cou+=1
tmp.append(tampung)
print(tmp)
output : [[1, 2, 3], [1, 2, 5]]
expected output : [[1,2,3],[2,4,10]]
Please help

List-expression are sth wonderful in Python.
result = [[x*y for y in l] for x, l in zip(dataB, dataA)]
This does the same like:
result = []
for x, l in zip(dataB, dataA):
temp = []
for y in l:
temp.append(x * y)
result.append(temp)
result
## [[1, 2, 3], [2, 4, 10]]

If you are working with numbers consider using numpy as it will make your operations much easier.
dataA = [[1,2,3],[1,2,5]]
dataB = [1,2]
# map list to array
dataA = np.asarray(dataA)
dataB = np.asarray(dataB)
# dataA = array([[1, 2, 3], [1, 2, 5]])
# 2 x 3 array
# dataB = array([1, 2])
# 1 x 2 array
dataC_1 = dataA[0] * dataB[0] #multiply first row of dataA w/ first row of dataB
dataC_2 = dataA[1] * dataB[1] #multiply second row of dataA w/ second row of dataB
# dataC_1 = array([1, 2, 3])
# dataC_2 = array([2, 4, 10])
These arrays can always be cast back into lists by passing them into List()
As other contributors have said, please look into the numpy library!

Related

I want an efficient way of comparing columns of data to make a decision

I have a CSV file that I read using pandas. I would like to make a comparison between some of the columns and then use the outcome of the comparison to make a decision. An example of the data is shown below.
A
B
C
D
6
[5, 3, 4, 1]
-4.2974843
[-5.2324843, -5.2974843, -6.2074043, -6.6974803]
2
[3, 6,4, 7]
-6.4528433
[-6.2324843, -7.0974845, -7.2034041, -7.6974804]
3
[6, 2, 4, 5]
-3.5322451
[-4.3124440, -4.9073840, -5.2147042, -6.1904800]
1
[4, 3, 6,2]
-5.9752843
[-5.2324843, -5.2974843, -6.2074043, -6.6974803]
7
[2, 3, 4, 1]
-1.2974652
[-3.1232843, -4.2474643, -5.2074043, -6.1994802]
5
[1, 3, 7, 2]
-9.884843
[-8.0032843, -8.0974843, -9.2074043, -9.6904603]
4
[7, 3, 1, 4]
-2.3984843
[-7.2324843, -8.2094845, -9.2044013, -9.7914001]
Here is the code I am using:
n_A = data['A']
n_B = data['B']
n_C = data['C']
n_D = data['D']
result_compare = []
for w, e in enumerate(n_A):
for ro, ver in enumerate(n_B):
for row, m in enumerate(n_C):
for r, t in enumerate(n_D):
if ro==w:
if r ==row:
if row==ro:
if r==0:
if t[r]>m:
b = ver[r]
result_compare.append(b)
else:
b = e
result_compare.append(b)
elif r>=0:
q = r-r
if t[q]>m:
b = ver[q]
result_compare.append(b)
else:
b = e
result_compare.append(b)
I had to select only the columns required for the comparison and that was why I did the following.
n_A = data['A']
n_B = data['B']
n_C = data['C']
n_D = data['D']
Results could be as:
result_compare = [6, 3 , 3, 4, 7 , 1, 4 ]
The values in D are arranged in descending order which is why the first element of the list is selected in this case. So when the first element in the row of the list D is greater than the one of C, we choose the first element of the list B, otherwise A. I would like an efficient way since my code takes lots of time to provide results most especially in the case of large data.
I would do this in your case
data['newRow']=data.apply(lambda row: row["B"][0] if row["D"][0] > row["C"] else row['A'], axis=1)
And if you need it as a list by the end:
list(data['newRow'])

Random change of rows of two matrices using indices

Any idea or clue about writing below problem code in python 3.6?
Imagine I have matrix A and B as below:
A = [1 2, 3 4, 5 6] with the dimension of 3*2
B = [1, 3, 5] with the dimension of 3*1
Now I want to change the rows randomly using indices.
for instance index 1 related to [1 2] from A and [1] from B, index 2 related to [3 4] from A and [3] from B, index 3 related to [5 6] from A and [5] from B.
Imagine randomly I order the indices as 2, 3, 1, now my output will be:
A=[3 4, 5 6, 1 2]
B=[3, 5, 1]
import numpy as np
A = [[1, 2],[3, 4], [5, 6]]
A = np.array(A)
B = [[1], [3], [5]]
B = np.array(B)
import random
def rand(n):
l = list(range(n))
random.shuffle(l)
l = np.reshape(l, (n,1)) return l l = rand(3)
print(l)
AF = []
AFF = []
BF = []
BFF = []
for i in range (0, len(A)):
AF = A[l[i]]
AFF.extend(AF)
BF = B[l[i]]
BFF.extend(BF)
B = np.array(BFF)
A = np.array(AFF)
print(B)
print(A)

Please explain me this code?

rez = [[m[j][i] for j in range(len(m))] for i in range(len(m[0]))]
I am not able to understand how it will print the transpose when we use it in for loop . Can someone explain the working thoroughly ?
#Parakh, you did not specify what m is, so I made it a 2d array:
m = [[6, 2],
[3, 4]]
rez = [[m[j][i] for j in range(len(m))] for i in range(len(m[0]))]
print(rez)
[[6, 3], [2, 4]]
This is the same as:
```
m = [[6, 2],
[3, 4]]
rez = []
for i in range(len(m[0])):
temp = []
for j in range(len(m)):
temp.append(m[j][i])
rez.append(temp)
print(rez)
```
This is producing column 0, row 0 (6) and column 0, row 1 (3) as the first new list,
then column 1, row 0 (2) and column 1, row 1 (4) as the second new list.
j is the row index, i is the column index.
i[0], j[0] = 6
i[0], j[1] = 3
i[1], j[0] = 2
i[1], j[1] = 4

pandas: aggregate a column of list into one list

I have the following data frame my_df:
name numbers
----------------------
A [4,6]
B [3,7,1,3]
C [2,5]
D [1,2,3]
I want to combine all numbers to a new list, so the output should be:
new_numbers
---------------
[4,6,3,7,1,3,2,5,1,2,3]
And here is my code:
def combine_list(my_lists):
new_list = []
for x in my_lists:
new_list.append(x)
return new_list
new_df = my_df.agg({'numbers': combine_list})
but the new_df still looks the same as original:
numbers
----------------------
0 [4,6]
1 [3,7,1,3]
2 [2,5]
3 [1,2,3]
What did I do wrong? How do I make new_df like:
new_numbers
---------------
[4,6,3,7,1,3,2,5,1,2,3]
Thanks!
You need flatten values and then create new Dataframe by constructor:
flatten = [item for sublist in df['numbers'] for item in sublist]
Or:
flatten = np.concatenate(df['numbers'].values).tolist()
Or:
from itertools import chain
flatten = list(chain.from_iterable(df['numbers'].values.tolist()))
df1 = pd.DataFrame({'numbers':[flatten]})
print (df1)
numbers
0 [4, 6, 3, 7, 1, 3, 2, 5, 1, 2, 3]
Timings are here.
You can use df['numbers'].sum() which returns a combined list to create the new dataframe
new_df = pd.DataFrame({'new_numbers': [df['numbers'].sum()]})
new_numbers
0 [4, 6, 3, 7, 1, 3, 2, 5, 1, 2, 3]
This should do:
newdf = pd.DataFrame({'numbers':[[x for i in mydf['numbers'] for x in i]]})
Check this pandas groupby and join lists
What you are looking for is,
my_df = my_df.groupby(['name']).agg(sum)

Returning the N largest values' indices in a multidimensional array (can find solutions for one dimension but not multi-dimension)

I have a numpy array X, and I'd like to return another array Y whose entries are the indices of the n largest values of X i.e. suppose I have:
a =np.array[[1, 3, 5], [4, 5 ,6], [9, 1, 7]]
then say, if I want the first 5 "maxs"'s indices-here 9, 7 , 6 , 5, 5 are the maxs, and their indices are:
b=np.array[[2, 0], [2 2], [ 2 1], [1 1], [0 , 2])
I've been able to find some solutions and make this work for a one dimensional array like
c=np.array[1, 2, 3, 4, 5, 6]:
def f(a,N):
return np.argsort(a)[::-1][:N]
But have not been able to generate something that works in more than one dimension. Thanks!
Approach #1
Get the argsort indices on its flattened version and select the last N indices. Then, get the corresponding row and column indices -
N = 5
idx = np.argsort(a.ravel())[-N:][::-1] #single slicing: `[:N-2:-1]`
topN_val = a.ravel()[idx]
row_col = np.c_[np.unravel_index(idx, a.shape)]
Sample run -
# Input array
In [39]: a = np.array([[1,3,5],[4,5,6],[9,1,7]])
In [40]: N = 5
...: idx = np.argsort(a.ravel())[-N:][::-1]
...: topN_val = a.ravel()[idx]
...: row_col = np.c_[np.unravel_index(idx, a.shape)]
...:
In [41]: topN_val
Out[41]: array([9, 7, 6, 5, 5])
In [42]: row_col
Out[42]:
array([[2, 0],
[2, 2],
[1, 2],
[1, 1],
[0, 2]])
Approach #2
For performance, we can use np.argpartition to get top N indices without keeping sorted order, like so -
idx0 = np.argpartition(a.ravel(), -N)[-N:]
To get the sorted order, we need one more round of argsort -
idx = idx0[a.ravel()[idx0].argsort()][::-1]

Resources