Should I use bracket or parenthesis in creating numpy array? - python

For example, these two syntaxes seems to be same:
In [3]: np.random.random((3,2))
Out[3]:
array([[0.12612127, 0.81236009],
[0.12289859, 0.89502736],
[0.70360669, 0.51271339]])
In [4]: np.random.random([3,2])
Out[4]:
array([[0.94723024, 0.55169203],
[0.48919411, 0.22082705],
[0.24072127, 0.88963255]])
So either one is ok?

Related

How to use Wildcard in Numpy array operations?

For instance, define a numpy array with numpy.str_ format and doing the replace operation supported by numpy.char:
import numpy as np
a = np.array(['a-b-c-d','e-f-g-h'],np.str_)
print (np.char.replace(a,'*-','i-'))
The returned result would be ['a-b-c-d', 'e-f-g-h'] but ['i-i-i-d', 'i-i-i-h'] is expected.
Is there any reason to use numpy arrays? You can't use wildcards with numpy.char.replace.
I would suggest to use python lists here and the re module:
l = ['a-b-c-d', 'e-f-g-h']
import re
out = [re.sub('.-', 'i-', i) for i in l]
Output: ['i-i-i-d', 'i-i-i-h']

Resizing an array to another shape in Python

I have the following array:
a = np.random.rand(5,2)
a
array([[0.98736372, 0.07639041],
[0.45342928, 0.4932295 ],
[0.75789786, 0.48546238],
[0.85854235, 0.74868237],
[0.13534155, 0.79317482]])
and I want to resize it so that it is divided into 2 batches with three elements (adding zeros as required):
array([[[0.98736372, 0.07639041],
[0.45342928, 0.4932295 ],
[0.75789786, 0.48546238]],
[[0.85854235, 0.74868237],
[0.13534155, 0.79317482],
[0, 0]]])
I have tried this, but it returns None:
a = a.copy()
a.resize((2,3,2), refcheck = False)
I believe .reshape would not provide the solution, as it is not able to fill in with 0's to comply with the desired dimensions for the array.
Using numpy.resize, you have to use like this:
import numpy as np
a = np.random.rand(5,2)
b = np.resize(a, (2,3,2))
otherwise you can use the object method to get the same result, like this:
import numpy as np
a = np.random.rand(5,2)
a.np.resize(2,3,2)
b = a.copy()
note the first one return ndarray and the last one returns None because It changes the object itself. For more info, look the numpy.resize doc

How to create numpy arrays automatically?

I wanted to create arrays by for loop to assign automatically array names.
But using a for loop, it didn't work and creating a dictionary with numpy.array() in it, does not work, too. Currently, I have no more ideas...
I am not really safe in handling with python.
import numpy as np
for file_name in folder:
file_name = np.array()
file_name.extend((blabla, blabla1))
I expected to get arrays with automatically assigned names, like file_name1, file_name2, ...
But I got the advice, "redeclared file_name defined above without usage" and the output was at line file_name = np.array()
TypeError: array() missing required argument 'object' (pos 1) ...
You can do it with globals() if you really want to use the strings as named variables.
globals()[filename] = np.array()
Example:
>>> globals()['test'] = 1
>>> test
1
Of course this populates the global namespace. Otherwise, you can use locals().
As #Mark Meyer said in comment, you should use dictionary (dict in Python) by setting file_name as key.
As per your error, when you create a numpy array, you should provide an iterable (ex. a list).
For example:
>>> folder = ['file1', 'file2']
>>> blabla = 0
>>> blabla1 = 1
>>> {f: np.array((blabla, blabla1)) for f in folder}
{'file1': array([0, 1]), 'file2': array([0, 1])}

Python Class dynamic attribute access

I want to access a class attribute by a string with its name.
Something like:
class a:
b=[]
c='b'
eval('a.'+c+'=1')
But that doesn't work in Python.
How can I do this?
Use setattr:
In [1]: class a:
...: b = []
...:
In [2]: setattr(a, 'b', 1)
In [3]: a.b
Out[3]: 1
Use getattr for the reverse:
In [4]: getattr(a, 'b')
Out[4]: 1
In [5]: getattr(a, 'x', 'default')
Out[5]: 'default'
I very much suspect, though, that there is a better way to achieve whatever your goal is. Have you tried using a dictionary instead of a class?
eval is for evaluation, use exec to 'execute' statements:
exec('a.'+c+'=1')
Yet, consider the risk of using both. And you can check out this answer for the difference between expressions and statements.
Since you are looking to set attribute by name, setattr explained in hop's answer is a better practice, and safer than using exec.

Can you increment a slice in python?

I'm trying out numpy by porting over some code I wrote in matlab/octave. In matlab, I can define the equivalent of a python slice, and then increment it as needed. For example, in my matlab code I have
HXx_range = 1:NHXx;
HXy_range = 1:NHXy;
blah blah blah
Hx(HXx_range, HXy_range) = Da(Hx_media(HXx_range, HXy_range)).*Hx(HXx_range, HXy_range) + Db(Hx_media(HXx_range, HXy_range)).*(Ez(HXx_range,HXy_range) - Ez(HXx_range,**HXy_range+1**));
Hy(HYx_range, HYy_range) = Da(Hy_media(HYx_range, HYy_range)).*Hy(HYx_range, HYy_range) + Db(Hy_media(HYx_range, HYy_range)).*(Ez(**HYx_range+1**,HYy_range) - Ez(HYx_range,HYy_range));
Ez(EZx_range, EZy_range) = Ca(Ez_media(EZx_range, EZy_range)).*Ez(EZx_range, EZy_range) + Cb(Ez_media(EZx_range, EZy_range)).*(Hy(EZx_range,EZy_range) - Hy(**EZx_range-1**,EZy_range) + Hx(EZx_range,**EZy_range-1**) - Hx(EZx_range,EZy_range));
The terms in '**'s (like 'HXy_range+1') are they key parts; HXy_range+1 is equal to 2:(NHXy+1). In python, I can define a slice in a similar way:
HXx_range = slice(0, NHXx)
However, HXx_range+1 gives me an error. Of course, I can just make a new slice for that, but it's not as clean. Is there a way around this?
Thanks.
If you define your HXy_range as a numpy array, then you can increment it as desired. If and when you wish to use it as a slice, you can form slice(*HXy_range):
In [26]: HXy_range = np.array([1,10])
In [27]: HXy_range+1
Out[27]: array([ 2, 11])
In [28]: slice(*(HXy_range+1))
Out[30]: slice(2, 11, None)
No, Python slice instances are immutable. To use standard slice instances, you must create a new one each time. Unfortunately, you can't subclass slice either.

Categories

Resources