I'm using ipython 4.0.1 and python 3.5.1, when I call np.c_(), it shows an error
CClass object is not callable.
This is my code:
import numpy as np
rows = []
with open('ntumlone.dat') as f:
rows = [list(map(float, L.split())) for L in f]
arr = np.array(rows)
date = np.c_(np.ones(len(arr)), arr)
What's wrong with me?
Try
date = np.c_[np.ones(len(arr)), arr]
Check its docs. You 'call' it with square brackets, as though you are indexing, not with (). If the distinction is too confusing stick with concatenate or one of the stack functions. I think in this use it is the same as vstack.
Related
I am learning Python and have been trying out some simple equations using NumPy. While trying to calculate the mean of a list of numbers using the mean() function, I encountered an error.
AttributeError: 'list' object has no attribute 'mean'
P.S To avoid any doubt, Numpy has been installed via pip and works fine. In addition, the two list objects are intentionally different shapes.
Here is my script/code:
import numpy as np
family_name = ['Homer','Marge','Maggie']
family_age = [39,36,2,8]
family_name_age = np.array([family_name, family_age], dtype=object)
avg_family_age = family_name_age[1].mean()
print('Average age: {:.2f}'.format(avg_family_age))
When I run this in a jupyter notebook, I get the following error message.
AttributeError
Traceback (most recent call last) c:\Users\my_pc\a_folder\01-numpy-practice.ipynb
in <cell line: 5>()
2 family_age = [39,36,2,8]
3 family_name_age= np.array([family_name, family_age], dtype=object)
----> 4 avg_family_age = family_name_age[1].mean()
6 print('Average age: {:.2f}'.format(avg_family_age))
AttributeError: 'list' object has no attribute 'mean'
However, when I try mean() as follows it works fine:
family_height_cm = [183,172,82]
family_weight_kg = [109,60,11]
family_bmi_data = np.array([family_height_cm,family_weight_kg])
avg_fam_height = family_bmi_data[0].mean()
print('Average height: {:.2f}'.format(avg_fam_height))
It works perfectly and I get a figure of Average height: 145.67
It would be very helpful if someone could give me some insight into what I'm doing wrong and an explanation of the theory that is as simple as possible. Mega thank you in advance.
In the first example, you are specifying the dtype as object. This will leave you with an array of two python lists. You cannot call .mean() on a python list.
family_name_age[1] is a list, but family_bmi_data[0] is a NumPy array. Unlike a NumPy array, a list does not have a mean method.
#jprebys provided a clear reason why I encountered the error: "AttributeError: 'list' object has no attribute 'mean'"
In the first example, you are specifying the dtype as object. This
will leave you with an array of two python lists. You cannot call
.mean() on a python list - #jprebys https://stackoverflow.com/a/74116157/1753769
While #learner provided a code snippet that enabled me to achieve the result I was aiming for.
By first setting my variable: family_age as a NumPy array: family_age = np.array([39,36,2,8]). I was able to use the mean method/function as needed.
So my full code block as provided by #learner looked like this:
family_name = ['Homer','Marge','Maggie']
family_age = np.array([39,36,2,8])
family_name_age= np.array([family_name, family_age], dtype=object)
avg_family_age = family_name_age[1].mean()
print('Average age: {:.2f}'.format(avg_family_age))
Thank you #learner and #jprebys
With python3.8, a new feature is self documenting format strings. Where one would normally do this:
>>> x = 10.583005244
>>> print(f"x={x}")
x=10.583005244
>>>
One can now do this, with less repetition:
>>> x = 10.583005244
>>> print(f"{x=}")
x=10.583005244
>>>
This works very well for one line string representations. But consider the following scenario:
>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array([[0.05281443, 0.06559171],
[0.13017109, 0.69505908],
[0.60807431, 0.58159127],
[0.92113252, 0.4950851 ]])
>>>
Here, the first line does not get aligned, which is (arguably) not desirable. I would rather prefer the output of the following:
>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"some_fairly_long_named_arr=\n{some_fairly_long_named_arr!r}")
some_fairly_long_named_arr=
array([[0.06278696, 0.04521056],
[0.33805303, 0.17155518],
[0.9228059 , 0.58935207],
[0.80180669, 0.54939958]])
>>>
Here, the first line of the output is aligned as well, but it defeats the purpose of not repeating the variable name twice in the print statement.
The example is a numpy array, but it could have been a pandas dataframe etc. as well.
Hence, my question is: Can a newline character be inserted after the = sign in self documenting strings?
I tried to add it like this, but it does not work:
>>> print(f"{some_fairly_long_named_arr=\n}")
SyntaxError: f-string expression part cannot include a backslash
I read the docs on format-specification-mini-language, but most of the formatting there only works for simple data types like integers, and I was not able to achieve what I wanted using those that work.
Sorry for the long write-up.
Wouldn't recommend this at all, but for possibility's sake:
import numpy as np
_old_array2string = np.core.arrayprint._array2string
def _array2_nice_string(*args, **kwargs):
non_nice_string = _old_array2string(*args, **kwargs)
dimension_strings = non_nice_string.split("\n")
if len(dimension_strings) > 1:
dimension_string = dimension_strings[1]
dimension_indent = len(dimension_string) - len(dimension_string.lstrip())
return "\n" + " " * dimension_indent + non_nice_string
return non_nice_string
np.core.arrayprint._array2string = _array2_nice_string
Outputs for:
some_fairly_long_named_arr = np.random.rand(2, 2)
print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array(
[[0.95900608, 0.79367873],
[0.58616975, 0.17757661]])
and
some_fairly_long_named_arr = np.random.rand(1, 2)
print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array([[0.62492772, 0.80453153]]).
I made it so if if the first dimension is 1, it is kept on the same line.
There is a non-internal method np.array2string that I tried to re-assign, but I never got that working. If someone could find a way to re-assign that public function instead of this internally used one, I'd imagine that'd make this solution a lot cleaner.
I figured out a way to accomplish what I wanted, after reading through the CPython source:
import numpy as np
some_fairly_long_named_arr = np.random.rand(4, 2)
print(f"""{some_fairly_long_named_arr =
}""")
Which produces:
some_fairly_long_named_arr =
array([[0.23560777, 0.96297907],
[0.18882751, 0.40712246],
[0.61351814, 0.1981144 ],
[0.27115495, 0.72303859]])
I would rather prefer a solution that worked in a single line, but this seems to be the only way for now. Perhaps another way will be implemented in a later python version.
However note that the indentation on the continuation line has to be removed for the above mentioned method, as such:
# ...some code with indentation...
print(f"""{some_fairly_long_named_arr =
}""")
# ...more code with indentation...
Otherwise, the alignment of the first line is broken again.
I tried using inspect.cleandoc and textwrap.dedent to alleviate this, but could not manage to fix the indentation issue. But perhaps this is the subject of another question.
Edit: After reading this article, I found a single line solution:
f_str_nl = lambda object: f"{chr(10) + str(object)}" # add \n directly
# f_str_nl = lambda object: f"{os.linesep + str(object)}" # add \r\n on windows
print(f"{f_str_nl(some_fairly_long_named_arr) = !s}")
which outputs:
f_str_nl(some_fairly_long_named_arr) =
[[0.26616956 0.59973262]
[0.86601261 0.10119292]
[0.94125617 0.9318651 ]
[0.10401072 0.66893025]]
The only caveat is that the name of the object gets prepended by the name of the custom lambda function, f_str_nl.
I also found that a similar question was already asked here.
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])}
How can I transfer
A = [0.12075357905088335, -0.192198145631724, 0.9455373400335009, -0.6811922263715244, 0.7683786941009969, 0.033112227984689206, -0.3812622359989405]
to
A = [[0.12075357905088335], [-0.192198145631724], [0.9455373400335009], [-0.6811922263715244], [0.7683786941009969], [0.033112227984689206], [-0.3812622359989405]]
I tried to the code below but an error occurred:
new = []
for i in A:
new.append.list(i)
TypeError: 'float' object is not iterable
Could anyone help me?
tl;dr
Try list comprehension, it is much more convenient:
new = [[i] for i in A]
Explanation
You are getting TypeError because you cannot apply list() function to value of type float. This function takes an iterable as a parameter and float is not an iterable.
Another mistake is that you are using new.append._something instead of new.append(_something): append is a method of a list object, so you should provide an item to add as a parameter.
You have a mistake, try:
new = []
for i in A:
new.append([i])
Here is more beautiful solution:
new = [[i] for i in A]
list.append is a method which requires an argument, e.g. new.append(i) or, in this case new.append([i]).
A list comprehension is a better idea, see #IvanVinogradov's solution.
If you are happy using a 3rd party library, consider numpy for a vectorised solution:
import numpy as np
A = [0.12075357905088335, -0.192198145631724, 0.9455373400335009, -0.6811922263715244, 0.7683786941009969, 0.033112227984689206, -0.3812622359989405]
A = np.array(A)[:, None]
print(A)
# [[ 0.12075358]
# [-0.19219815]
# [ 0.94553734]
# [-0.68119223]
# [ 0.76837869]
# [ 0.03311223]
# [-0.38126224]]
I think you are using like that:
my_data=b['dataset']['data'][0][1]
useful_data=[i[1] for i in my_data]
So when you compile it gives you an error:
TypeError: 'float' object is not iterable
Try only:
my_data=b['dataset']['data']
Then you will get your data.
I'm having some trouble to understand the mapping with rpy2 object and python object.
I have a function(x) which return a tuple object in python, and i want to map this tuple object with R object list or vector.
First, i'm trying to do this :
# return a python tuple into this r object tlist
robjects.r.tlist = get_max_ticks(x)
#Convert list into dataframe
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
FAIL with error :
rinterface.RRuntimeError: Error in eval(expr, envir, enclos) : object 'tlist' not found
So i'm trying an other strategy :
robjects.r["tlist"] = get_max_ticks(x)
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
FAIL with this error :
TypeError: 'R' object does not support item assignment
Could you help me to understand ?
Thanks a lot !!
Use globalEnv:
import rpy2.robjects as ro
r=ro.r
def get_max_ticks():
return (1,2)
ro.globalEnv['tlist'] = ro.FloatVector(get_max_ticks())
r('x <- as.data.frame(tlist,row.names=c("seed","ticks"))')
print(r['x'])
# tlist
# seed 1
# ticks 2
It may be possible to access symbols in the R namespace with this type of notation: robjects.r.tlist, but you can not assign values this way. The way to assign symbol is to use robject.globalEnv.
Moreover, some symbols in R may contain a period, such as data.frame. You can not access such symbols in Python using notation similar to robjects.r.data.frame, since Python interprets the period differently than R. So I'd suggest avoiding this notation entirely, and instead use
robjects.r['data.frame'], since this notation works no matter what the symbol name is.
You could also avoid the assignment in R all together:
import rpy2.robjects as ro
tlist = ro.FloatVector((1,2))
keyWordArgs = {'row.names':ro.StrVector(("seed","ticks"))}
x = ro.r['as.data.frame'](tlist,**keyWordArgs)
ro.r['print'](x)