How to properly swap numpy array - arrays

I am trying to swap the named columns of a numpy array as shown below, but the function is not behaving accordingly to what I anticipated. I see that the original 'data' is being changed even when I use the deepcopy from the copy module. Is there something that I am missing?
import copy
import numpy as np
data = np.array([(1.0, 2), (3.0, 4)], dtype=[('x', float), ('y',float)])
def rot(data, i):
rotdata = copy.deepcopy(data)
print(data['x'])
if i == 0:
pass
if i == 1:
rotdata['x'] = 5-rotdata['x']
if i == 2:
rotdata.dtype.names = ['y','x']
if i == 3:
rotdata.dtype.names = ['y','x']
rotdata['x'] = 5-rotdata['x']
if i == 4:
rotdata['x'] = 5-rotdata['x']
rotdata.dtype.names = ['y','x']
if i == 5:
rotdata['x'] = 5-rotdata['x']
rotdata.dtype.names = ['y','x']
rotdata['x'] = 5-rotdata['x']
return rotdata
data1 = rot(data,5)
data2 = rot(data,5)
print(data1)
print(data2)
The result is,
[1. 3.]
[2. 4.]
[(4., 3.) (2., 1.)]
[(1., 2.) (3., 4.)]
Which is indeed against my intentions.

Apparently copy.deepcopy() does not make a deep copy of the dtype object attached to the numpy array. So the data inside the array was copied, but you were switching names 'x' and 'y' in the data.dtype. So printing data['x'] gave you a different result, as did the second call data2 = rot(data,5).
You can solve it by adding the following line:
rotdata = copy.deepcopy(data)
rotdata.dtype = copy.deepcopy(data.dtype)

Related

Storing numpy.ndarrays from a loop

I am trying to store the numpy.ndarrays defined as x_c, y_c, and z_c for every iteration of the loop:
for z_value in np.arange(0, 5, 1):
ms.set_current_mesh(0)
planeoffset : float = z_value
ms.compute_planar_section(planeaxis = 'Z Axis', planeoffset = planeoffset)
m = ms.current_mesh()
matrix_name = m.vertex_matrix()
x_c = matrix_name[:,0]
y_c = matrix_name[:,1]
z_c = matrix_name[:,2]
I would like to be able to recall the three arrays at any z_value, preferably with reference to the z_value i.e x_c # z_value = 2 or similar.
Thanks for any help!
p.s very new to coding, so please go easy on me.
You have to store each array in an external variable, for example a dictionary
x_c={}
y_c={}
z_c={}
for z_value in np.arange(0, 5, 1):
ms.set_current_mesh(0)
planeoffset = float(z_value)
ms.compute_planar_section(planeaxis = 'Z Axis', planeoffset = planeoffset)
m = ms.current_mesh()
m.compact()
print(m.vertex_number(), "vertices in Planar Section Z =", planeoffset)
matrix_name = m.vertex_matrix()
x_c[planeoffset] = matrix_name[:,0]
y_c[planeoffset] = matrix_name[:,1]
z_c[planeoffset] = matrix_name[:,2]
Please, ensure you call m.compact() before accessing the vertex_matrix or you will get a MissingCompactnessException error. Please, note that it is not the same to store anything in x_c[2] or in x_c[2.0], so choose if your index has to be integers o floats and keep the same type (in this example, they are floats).
Later, you can recall values like this:
print("X Values with z=2.0")
print(x_c[2.0])

Run parallel loops in Ruby

I have two sets of arrays stored in a file and I need to extract values one by one and compare them. I am using this code but does look like I am doing correctly.
# First Dataset
File.foreach(file_set_a) do |data_a|
data_array_a = data_a.split("\t")
#file_name_a = data_array_a[0]
#file_ext_a = data_array_a[1]
# Second Dataset
File.foreach(file_set_b) do |data_b|
data_array_b = data_b.split("\t")
#file_name_b = data_array_b[0]
#file_ext_b = data_array_b[1]
#Compare
#file_name_a == #file_name_b
end
end
The problem is, I cannot go back and extract the next values in the set A when I enter the set B. Any suggestions?
First, convert those 2 files into two separated data arrays
lines_array_a = File.readlines(file_set_a)
lines_array_b = File.readlines(file_set_b)
I am assuming both of the array size will be same. Now run a loop and get the items from both array to compare them.
for i in 0..(lines_array_a.count - 1) do
data_array_a = lines_array_a[i].split("\t")
#file_name_a = data_array_a[0]
#file_ext_a = data_array_a[1]
data_array_b = lines_array_b[i].split("\t")
#file_name_b = data_array_b[0]
#file_ext_b = data_array_b[1]
#file_name_a == #file_name_b
end

numpy slicing using user defined input

I have (in a larger project) data contained in numpy.array.
Based on user input I need to move a selected axis (dimAxisNr) to the first dimension of the array and slice one or more (including the first) dimension based on user input (such as Select2 and Select0 in the example).
Using this input I generate a DataSelect which contains the information needed to slice. But the output size of the sliced array is different from the one using inline indexing. So basically I need a way to generate the '37:40:2' and '0:2' from an input list.
import numpy as np
dimAxisNr = 1
Select2 = [37,39]
Select0 = [0,1]
plotData = np.random.random((102,72,145,2))
DataSetSize = np.shape(plotData)
DataSelect = [slice(0,item) for item in DataSetSize]
DataSelect[2] = np.array(Select2)
DataSelect[0] = np.array(Select0)
def shift(seq, n):
n = n % len(seq)
return seq[n:] + seq[:n]
#Sort and Slice the data
print(np.shape(plotData))
print(DataSelect)
plotData = np.transpose(plotData, np.roll(range(plotData.ndim),-dimAxisNr))
DataSelect = shift(DataSelect,dimAxisNr)
print(DataSelect)
print(np.shape(plotData))
plotData = plotData[DataSelect]
print(np.shape(plotData))
plotDataDirect = plotData[slice(0, 72, None), 37:40:2, slice(0, 2, None), 0:2]
print(np.shape(plotDataDirect))
I'm not sure I've understood your question at all...
But if the question is "How do I generate a slice based on a list of indices like [37,39,40,23] ?"
then I would answer : you don't have to, just use the list as is to select the right indices, like so :
a = np.random.rand(4,5)
print(a)
indices = [2,3,1]
print(a[0:2,indices])
Note that the sorting of the list matters: [2,3,1] yields a different result from [1,2,3]
Output :
>>> a
array([[ 0.47814802, 0.42069094, 0.96244966, 0.23886243, 0.86159478],
[ 0.09248812, 0.85569145, 0.63619014, 0.65814667, 0.45387509],
[ 0.25933109, 0.84525826, 0.31608609, 0.99326598, 0.40698516],
[ 0.20685221, 0.1415642 , 0.21723372, 0.62213483, 0.28025124]])
>>> a[0:2,[2,3,1]]
array([[ 0.96244966, 0.23886243, 0.42069094],
[ 0.63619014, 0.65814667, 0.85569145]])
I have found the answer to my question. I need to use numpy.ix_.
Here is the working code:
import numpy as np
dimAxisNr = 1
Select2 = [37,39]
Select0 = [0,1]
plotData = np.random.random((102,72,145,2))
DataSetSize = np.shape(plotData)
DataSelect = [np.arange(0,item) for item in DataSetSize]
DataSelect[2] = Select2
DataSelect[0] = Select0
#print(list(37:40:2))
def shift(seq, n):
n = n % len(seq)
return seq[n:] + seq[:n]
#Sort and Slice the data
print(np.shape(plotData))
print(DataSelect)
plotData = np.transpose(plotData, np.roll(range(plotData.ndim),-dimAxisNr))
DataSelect = shift(DataSelect,dimAxisNr)
plotDataSlice = plotData[np.ix_(*DataSelect)]
print(np.shape(plotDataSlice))
plotDataDirect = plotData[slice(0, 72, None), 37:40:2, slice(0, 2, None), 0:1]
print(np.shape(plotDataDirect))

How to use arrays created by loop? Matlab

The code I'm using imports data from multiple files and saves them into an array of cells, the code is as follows:
[FileName,PathName,FilterIndex] = uigetfile('*.txt*','MultiSelect','on');
numfiles = size(FileName,2);
FileData= cell(1,numfiles);
for ii = 1:numfiles
FileName{ii};
A=[];
entirefile =fullfile(PathName,FileName{ii});
fid = fopen(entirefile);
tline = fgets(fid);
while ischar(tline)
parts = textscan(tline, '%f;');
if numel(parts{1}) > 0
A = [ A ; parts{:}' ];
end
tline = fgets(fid);
end
fclose(fid);
FileData{ii} = A;
A = FileData{ii};
X = A(:,1);
Y = A(:,5);
DataToUse = [X,Y];
end
Now my issue is I want to use the first DataToUse created by the loop, which will be data from the first file, seperatley to the other files but I can not issolate it. I have tried DataToUse(1), DataToUse(1,1) and DataToUse(:,[1,2]) but none are working for me. An example of the type of data would be:
DataToUse=
0.0762 0.0271
0.0763 0.2671
0.0764 0.4079
0.0765 0.0510
0.0766 0.0087
0.0767 0.0099
0.0768 0.0067
0.0769 0.0047
0.0770 0.0047
0.0771 0.0349
0.0772 0.2094
0.0773 0.2740
0.0774 0.0294
0.0775 0.0100
0.0776 0.0159
I have different numbers of this kind of data depending on how many files are selected but I would like to only use the first initially and use the others later. Anybody know how I can go about doing this? Many thanks in advance
The solution is to use cell arrays, like so:
DataToUse{ii} = [X, Y]
To get the desired output put this after your for-loop:
firstLoopXY = DataToUse{1}
Enjoy!

How does it make query ndb.AND condition more smart

I try to make query for tag search.
tags: how many tags ex.3
q: array of tags ex.['foo','hoo','poo']
def queryByTags(cls, tags, q):
def one():
qry = models.Card.query(models.Card.tags_value == q[0])
return qry
def two():
qry = models.Card.query(ndb.AND(models.Card.tags_value == q[0],
models.Card.tags_value == q[1]))
return qry
def three():
qry = models.Card.query(ndb.AND(models.Card.tags_value == q[0],
models.Card.tags_value == q[1],
models.Card.tags_value == q[2]))
return qry
tags_len = {1: one,
2: two,
3: three,
}
return tags_len[tags]()
This method can use up to 3 tags. I can copy code myself and extend it until 7,8,9...
It is very sad way...
Is there any smart way?
In pseudo python-ndb (I didn't run my code but you'll get it) I would say that a way would be to do:
cards_count = Card.query().filter(tags_value==q[0])\
.filter(tags_value==q[1])\
.filter(tags_value==q[2]).count()
or if iterating dynamic array (unknown length)
cards_count = Card.query()
for value in q:
q = q.filter(tags_value==value)
cards_count = q.count()

Resources