Storing multiple arrays in a np.zeros or np.ones - python

I'm trying to initialize a dummy array of length n using np.zeros(n) with dtype=object. I want to use this dummy array to store n copies of another array of length m.
I'm trying to avoid for loop to set values at each index.
I tried using the below code but keep getting error -
temp = np.zeros(10, dtype=object)
arr = np.array([1.1,1.2,1.3,1.4,1.5])
res = temp * arr
The desired result should be -
np.array([[1.1,1.2,1.3,1.4,1.5], [1.1,1.2,1.3,1.4,1.5], ... 10 copies])
I keep getting the error -
operands could not be broadcast together with shapes (10,) (5,)
I understand that this error arises since the compiler thinks I'm trying to multiply those arrays.
So how do I achieve the task?

np.tile() is a built-in function that repeats a given array reps times. It looks like this is exactly what you need, i.e.:
res = np.tile(arr, 2)

>>> arr = np.array([1.1,1.2,1.3,1.4,1.5])
>>> arr
array([1.1, 1.2, 1.3, 1.4, 1.5])
>>> np.array([arr]*10)
array([[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5],
[1.1, 1.2, 1.3, 1.4, 1.5]])

Related

How to use a different colormap for different rows of a heatmap

I am trying to change 1 row in my heatmap to a different color
here is the dataset:
m = np.array([[ 0.7, 1.4, 0.2, 1.5, 1.7, 1.2, 1.5, 2.5],
[ 1.1, 2.5, 0.4, 1.7, 2. , 2.4, 2. , 3.2],
[ 0.9, 4.4, 0.7, 2.3, 1.6, 2.3, 2.6, 3.3],
[ 0.8, 2.1, 0.2, 1.8, 2.3, 1.9, 2. , 2.9],
[ 0.9, 1.3, 0.8, 2.2, 1.8, 2.2, 1.7, 2.8],
[ 0.7, 0.9, 0.4, 1.8, 1.4, 2.1, 1.7, 2.9],
[ 1.2, 0.9, 0.4, 2.1, 1.3, 1.2, 1.9, 2.4],
[ 6.3, 13.5, 3.1, 13.4, 12.1, 13.3, 13.4, 20. ]])
data = pd.DataFrame(data = m)
Right now I am using seaborn heatmap, I can only create something like this:
cmap = sns.diverging_palette(240, 10, as_cmap = True)
sns.heatmap(data, annot = True, cmap = "Reds")
plt.show
I hope to change the color scheme of the last row, here is what I want to achieve (I did this in Excel):
Is it possible I achieve this in Python with seaborn heatmap? Thank you!
You can split in two, mask the unwanted parts, and plot separately:
# Reds
data1 = data.copy()
data1.loc[7] = float('nan')
ax = sns.heatmap(data1, annot=True, cmap="Reds")
# Greens
data2 = data.copy()
data2.loc[:6] = float('nan')
sns.heatmap(data2, annot=True, cmap="Greens")
output:
NB. you need to adapt the loc[…] parameter to your actual index names

How to pass argument of type char ** from Python to C API [duplicate]

As seen here How do I convert a Python list into a C array by using ctypes? this code will take a python array and transform it to a C array.
import ctypes
arr = (ctypes.c_int * len(pyarr))(*pyarr)
Which would the way of doing the same with a list of lists or a lists of lists of lists?
For example, for the following variable
list3d = [[[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]]]
I have tried the following with no luck:
([[ctypes.c_double * 4] *2]*3)(*list3d)
# *** TypeError: 'list' object is not callable
(ctypes.c_double * 4 *2 *3)(*list3d)
# *** TypeError: expected c_double_Array_4_Array_2 instance, got list
Thank you!
EDIT: Just to clarify, I am trying to get one object that contains the whole multidimensional array, not a list of objects. This object's reference will be an input to a C DLL that expects a 3D array.
It works with tuples if you don't mind doing a bit of conversion first:
from ctypes import *
list3d = [
[[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]],
[[0.2, 1.2, 2.2, 3.2], [4.2, 5.2, 6.2, 7.2]],
[[0.4, 1.4, 2.4, 3.4], [4.4, 5.4, 6.4, 7.4]],
]
arr = (c_double * 4 * 2 * 3)(*(tuple(tuple(j) for j in i) for i in list3d))
Check that it's initialized correctly in row-major order:
>>> (c_double * 24).from_buffer(arr)[:]
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2,
0.4, 1.4, 2.4, 3.4, 4.4, 5.4, 6.4, 7.4]
Or you can create an empty array and initialize it using a loop. enumerate over the rows and columns of the list and assign the data to a slice:
arr = (c_double * 4 * 2 * 3)()
for i, row in enumerate(list3d):
for j, col in enumerate(row):
arr[i][j][:] = col
I made the change accordingly
a = [[[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]]]
arr = (((ctypes.c_float * len(a[0][0])) * len(a[0])) * len(a))
arr_instance=arr()
for i in range(0,len(a)):
for j in range(0,len(a[0])):
for k in range(0,len(a[0][0])):
arr_instance[i][j][k]=a[i][j][k]
The arr_instance is what you want.

How to print a value to a new array if it within a bound of previous value in that array in Python/Numpy

If I have an array:
StartArray=np.array([1, 2, 3, 1.4, 1.2, 0.6, 1.8, 1.5, 1.9, 2.2, 3, 4 ,2.3])
I would like to loop through this array starting with StartArray[0] and only keep values that are within +/- .5 of the last kept value to yield:
EndArray=[1, 1.4, 1.2, 1.5, 1.9, 2.2, 2.3]
This is what I have tried so far and the results don't make sense
StartArray=np.array([1, 2, 3, 1.4, 1.2, 0.6, 1.8, 1.5, 1.9, 2.2, 3, 4 ,2.3])
EndArray=np.empty_like(StartArray)
EndArray[0]=StartArray[0]
for i in range(len(StartArray)-1):
if EndArray[i]+.5>StartArray[i+1]>EndArray[i]-.5:
EndArray[i+1]=StartArray[i+1]
Out:
array([ 1. , 0.22559146, 0.13015365, 5.24910493, 0.63804761,
0.6 , 1.73143364, 1.5 , 1.9 , 2.2 ,
6.82525036, 0.61641556, 6.82325036])
List is the good structure for this job:
StartArray=np.array([1, 2, 3, 1.4, 1.2, 0.6, 1.8, 1.5, 1.9, 2.2, 3, 4 ,2.3])
ref=StartArray[0]
End=[]
for x in StartArray:
if abs(x- ref)<.5:
End.append(x)
ref=x
print(np.array(End))
[ 1. 1.4 1.2 1.5 1.9 2.2 2.3]
There are multiple problems with your approach. First, you're initializing EndArray to be the same size as StartArray, but that's not what you want your desired output to be. Instead, initialize EndArray to be an empty list and append values as your loop through StartArray. Secondly, you want the output values to be within 0.5 of the last kept value, so you need to keep track of this.
Adapting your code:
StartArray=np.array([1, 2, 3, 1.4, 1.2, 0.6, 1.8, 1.5, 1.9, 2.2, 3, 4 ,2.3])
EndArray=[]
last_kept = StartArray[0]
EndArray.append(last_kept)
for i in range(len(StartArray)-1):
if np.abs(StartArray[i+1] - last_kept) < 0.5:
last_kept = StartArray[i+1]
EndArray.append(last_kept)
# convert back to numpy array
EndArray = np.array(EndArray)

how to merge the values of a list of lists and a list into 1 resulting list of lists

I have a list of lists (a) and a list (b) which have the same "length" (in this case "4"):
a = [
[1.0, 2.0],
[1.1, 2.1],
[1.2, 2.2],
[1.3, 2.3]
]
b = [3.0, 3.1, 3.2, 3.3]
I would like to merge the values to obtain the following (c):
c = [
[1.0, 2.0, 3.0],
[1.1, 2.1, 3.1],
[1.2, 2.2, 3.2],
[1.3, 2.3, 3.3]
]
currently I'm doing the following to achieve it:
c = []
for index, elem in enumerate(a):
x = [a[index], [b[index]]] # x assigned here for better readability
c.append(sum(x, []))
my feeling is that there is an elegant way to do this...
note: the lists are a lot larger, for simplicity I shortened them. they are always(!) of the same length.
In python3.5+ use zip() within a list comprehension and in-place unpacking:
In [7]: [[*j, i] for i, j in zip(b, a)]
Out[7]: [[1.0, 2.0, 3.0], [1.1, 2.1, 3.1], [1.2, 2.2, 3.2], [1.3, 2.3, 3.3]]
In python 2 :
In [8]: [j+[i] for i, j in zip(b, a)]
Out[8]: [[1.0, 2.0, 3.0], [1.1, 2.1, 3.1], [1.2, 2.2, 3.2], [1.3, 2.3, 3.3]]
Or use numpy.column_stack in numpy:
In [16]: import numpy as np
In [17]: np.column_stack((a, b))
Out[17]:
array([[ 1. , 2. , 3. ],
[ 1.1, 2.1, 3.1],
[ 1.2, 2.2, 3.2],
[ 1.3, 2.3, 3.3]])

How can a Python list be sliced such that a column is moved to being a separate element column?

I have a list of the following form:
[[0, 5.1, 3.5, 1.4, 0.2],
[0, 4.9, 3.0, 1.4, 0.2],
[0, 4.7, 3.2, 1.3, 0.2],
[1, 4.6, 3.1, 1.5, 0.2],
[1, 5.0, 3.6, 1.4, 0.2],
[1, 5.4, 3.9, 1.7, 0.4],
[1, 4.6, 3.4, 1.4, 0.3]]
I want to slice out the first column and add it as a new element to each row of data (so at each odd position in the list), changing it to the following form:
[[5.1, 3.5, 1.4, 0.2], [0],
[4.9, 3.0, 1.4, 0.2], [0],
[4.7, 3.2, 1.3, 0.2], [0],
[4.6, 3.1, 1.5, 0.2], [1],
[5.0, 3.6, 1.4, 0.2], [1],
[5.4, 3.9, 1.7, 0.4], [1],
[4.6, 3.4, 1.4, 0.3], [1],]
How could I do this?
So far, I have extracted the necessary information in the following ways:
targets = [element[0] for element in dataset]
features = dataset[1:]
Try indexing and then get flattened list- i used list comprehension for flattening.
>>>l=[[0, 5.1, 3.5, 1.4, 0.2],
[0, 4.9, 3.0, 1.4, 0.2],
[0, 4.7, 3.2, 1.3, 0.2],
[1, 4.6, 3.1, 1.5, 0.2],
[1, 5.0, 3.6, 1.4, 0.2],
[1, 5.4, 3.9, 1.7, 0.4],
[1, 4.6, 3.4, 1.4, 0.3]]
>>>[[i[1:],[i[0]]] for i in l]#get sliced list of lists
>>>[[[5.1, 3.5, 1.4, 0.2], [0]], [[4.9, 3.0, 1.4, 0.2], [0]], [[4.7, 3.2, 1.3, 0.2], [0]], [[4.6, 3.1, 1.5, 0.2], [1]], [[5.0, 3.6, 1.4, 0.2], [1]], [[5.4, 3.9, 1.7, 0.4], [1]], [[4.6, 3.4, 1.4, 0.3], [1]]]
>>>d=[[i[1:],[i[0]]] for i in l]
>>>[item for sublist in d for item in sublist]#flatten list d
>>>[[5.1, 3.5, 1.4, 0.2], [0], [4.9, 3.0, 1.4, 0.2], [0], [4.7, 3.2, 1.3, 0.2], [0], [4.6, 3.1, 1.5, 0.2], [1], [5.0, 3.6, 1.4, 0.2], [1], [5.4, 3.9, 1.7, 0.4], [1], [4.6, 3.4, 1.4, 0.3], [1]]
Just oneliner alternative-
[item for sublist in [[i[1:],[i[0]]] for i in l] for item in sublist] #Here l is that list
List comprehensions are nice but can be a bit hard to scan. Loops are still useful, especially when combined with extend:
res = []
for entry in dataset:
res.extend([entry[1:], entry[:1]])
now:
import pprint
pprint.pprint(res)
prints:
[[5.1, 3.5, 1.4, 0.2],
[0],
[4.9, 3.0, 1.4, 0.2],
[0],
[4.7, 3.2, 1.3, 0.2],
[0],
[4.6, 3.1, 1.5, 0.2],
[1],
[5.0, 3.6, 1.4, 0.2],
[1],
[5.4, 3.9, 1.7, 0.4],
[1],
[4.6, 3.4, 1.4, 0.3],
[1]]
Try this:
from itertools import chain
print list(chain(*[list((element[1:],[element[0]])) for element in a]))
Output:
[[5.1, 3.5, 1.4, 0.2], [0], [4.9, 3.0, 1.4, 0.2], [0],
[4.7, 3.2, 1.3, 0.2], [0], [4.6, 3.1, 1.5, 0.2], [1],
[5.0, 3.6, 1.4, 0.2], [1], [5.4, 3.9, 1.7, 0.4], [1],
[4.6, 3.4, 1.4, 0.3], [1]]
Slice each sublist and make a new list with an element for each slice:
l = [[0, 5.1, 3.5, 1.4, 0.2],
[0, 4.9, 3.0, 1.4, 0.2],
[0, 4.7, 3.2, 1.3, 0.2],
[1, 4.6, 3.1, 1.5, 0.2],
[1, 5.0, 3.6, 1.4, 0.2],
[1, 5.4, 3.9, 1.7, 0.4],
[1, 4.6, 3.4, 1.4, 0.3]]
>>> print(*[item for sub in l for item in (sub[1:], [sub[0]])], sep='\n')
[5.1, 3.5, 1.4, 0.2]
[0]
[4.9, 3.0, 1.4, 0.2]
[0]
[4.7, 3.2, 1.3, 0.2]
[0]
[4.6, 3.1, 1.5, 0.2]
[1]
[5.0, 3.6, 1.4, 0.2]
[1]
[5.4, 3.9, 1.7, 0.4]
[1]
[4.6, 3.4, 1.4, 0.3]
[1]
A Pythonic approach in python 3.X using unpacking iteration and itertools.chain:
>>> from itertools import chain
>>>
>>> list(chain.from_iterable([[j,[i]] for i,*j in A]))
[[5.1, 3.5, 1.4, 0.2], [0],
[4.9, 3.0, 1.4, 0.2], [0],
[4.7, 3.2, 1.3, 0.2], [0],
[4.6, 3.1, 1.5, 0.2], [1],
[5.0, 3.6, 1.4, 0.2], [1],
[5.4, 3.9, 1.7, 0.4], [1],
[4.6, 3.4, 1.4, 0.3], [1]]

Categories