Using Numpy, I am going to split an array of dimension (557124,2), dtype = "S10", in 6 subarrays using:
sub_arr = np.split(arr, 6)
Now I would like to use a for loop on savetxt and save the 6 subarrays to 6 .txt files.
I tried:
for i in sub_array:
np.savetxt(("Subarray", i, ".txt"), sub_array[i], fmt='%s')
There are 2 problems:
It's incorrect to say in sub_array. I should use range(5) but I want to make it adaptable to any number of sub arrays.
I thought I could use a sort of "paste" as in R when I did ("Subarray", i, ".txt"). Is there anything alike in Numpy?
Any idea?
From what I've understood
sub_arr = np.split(arr, 6)
returns a list of 6 numpy arrays. Then you can use enumerate to get each array and its index
fname_template = "Subarray.{i}.txt"
for i, sarr in enumerate(sub_arr):
np.savetxt(fname_template.format(i=i), sarr, fmt='%s')
To create the file name I've used the new string formatting. Otherwise you can concatenate strings with + as "Subarray."+str(i)+".txt", but you have to make sure that all the elements that you concatenate are strings.
Related
I am trying to apply a function over each row of a DataFrame as the code shows.
using RDatasets
iris = dataset("datasets", "iris")
function mean_n_var(x)
mean1=mean([x[1], x[2], x[3], x[4]])
var1=var([x[1], x[2], x[3], x[4]])
rst=[mean1, var1]
return rst
end
mean_n_var([2,4,5,6])
for row in eachrow(iris[1:4])
println(mean_n_var(convert(Array, row)))
end
However, instead of printing results, I'd like to save them in an array or another DataFrame.
Thanks in advance.
I thought it is worth to mention some more options available over what was already mentioned.
I assume you want a Matrix or a DataFrame. There are several possible approaches.
First is the most direct to get a Matrix:
mean_n_var(a) = [mean(a), var(a)]
hcat((mean_n_var(Array(x)) for x in eachrow(iris[1:4]))...) # rows
vcat((mean_n_var(Array(x)).' for x in eachrow(iris[1:4]))...) # cols
another possible approach is vectorized, e.g.:
mat_iris = Matrix(iris[1:4])
mat = hcat(mean(mat_iris, 2), var(mat_iris, 2))
df = DataFrame([vec(f(mat_iris, 2)) for f in [mean,var]], [:mean, :var])
DataFrame(mat) # this constructor also accepts variable names on master but is not released yet
so this is what I'm trying to do, and I'm not sure how cause I'm new to python. I've searched for a few options and I'm not sure why this doesn't work.
So I have 6 different nodes, in maya, called aiSwitch. I need to generate random different numbers from 0 to 6 and input that value in the aiSiwtch*.index.
In short the result should be
aiSwitch1.index = (random number from 0 to 5)
aiSwitch2.index = (another random number from 0 to 5 different than the one before)
And so on unil aiSwitch6.index
I tried the following:
import maya.cmds as mc
import random
allswtich = mc.ls('aiSwitch*')
for i in allswitch:
print i
S = range(0,6)
print S
shuffle = random.sample(S, len(S))
print shuffle
for w in shuffle:
print w
mc.setAttr(i + '.index', w)
This is the result I get from the prints:
aiSwitch1 <-- from print i
[0,1,2,3,4,5] <--- from print S
[2,3,5,4,0,1] <--- from print Shuffle (random.sample results)
2
3
5
4
0
1 <--- from print w, every separated item in the random.sample list.
Now, this happens for every aiSwitch, cause it's in a loop of course. And the random numbers are always a different list cause it happens every time the loop runs.
So where is the problem then?
aiSwitch1.index = 1
And all the other aiSwitch*.index always take only the last item in the list but the time I get to do the setAttr. It seems to be that w is retaining the last value of the for loop. I don't quite understand how to
Get a random value from 0 to 5
Input that value in aiSwitch1.index
Get another random value from 0 to 6 different to the one before
Input that value in aiSwitch2.index
Repeat until aiSwitch5.index.
I did get it to work with the following form:
allSwitch = mc.ls('aiSwitch')
for i in allSwitch:
mc.setAttr(i + '.index', random.uniform(0,5))
This gave a random number from 0 to 5 to all aiSwitch*.index, but some of them repeat. I think this works cause the value is being generated every time the loop runs, hence setting the attribute with a random number. But the numbers repeat and I was trying to avoid that. I also tried a shuffle but failed to get any values from it.
My main mistake seems to be that I'm generating a list and sampling it, but I'm failing to assign every different item from that list to different aiSwitch*.index nodes. And I'm running out of ideas for this.
Any clues would be greatly appreciated.
Thanks.
Jonathan.
Here is a somewhat Pythonic way: shuffle the list of indices, then iterate over it using zip (which is useful for iterating over structures in parallel, which is what you need to do here):
import random
index = list(range(6))
random.shuffle(index)
allSwitch = mc.ls('aiSwitch*')
for i,j in zip(allSwitch,index):
mc.setAttr(i + '.index', j)
I have a number of files (having 10 columns each) with following order:
file_001.txt, file_002.txt, file_003_txt,
file_021.txt, file_023.txt, file_023.txt,
file_041.txt, file_042.txt, file_043.txt,
file_061.txt, file_062.txt, file_063.txt,
file_081.txt, file_082.txt, file_083.txt,
I would like to plot each file with different line. e.g. using 1:2, using 1:3, using 1:5, using 1:8. I can not able to make a loop to call different columns. My following script is not working for k field
plot for [k=2, 3, 5, 8] for [j=0:8:2] for [i=1:3] 'file_0'.j.i.'.txt' u 1:k;
Use for [k in "2 3 5 8"] if you have a list rather than a range.
If j can be > 9, you should set up a function
fname(j,i) = sprintf("name%02.f%.f",j,i)
to get proper file names.
Format string "%02.f" means float (f), no digits after the comma (.), minimum two postions (2), fill empty space with zeroes.
print fname(2,3)
name023
print fname(13,3)
name133
print fname(113,3)
name1133
These are libc format strings, they are not documented inside the gnuplot docs, but there are many sources in the web.
Is there any way to dynamically create arrays in cython without using the horribly ugly kludge of malloc+pointer+free? There has to be some refcounting, garbage-collecting wrapper for this very basic function.
I need this to implement a ragged array.
inputs=[arr1,arr2,arr3,...]
...
NELEMENTS=len(inputs)
cdef np.ndarray[double,2] lookup[NELEMENTS] #<--- this is where I'm stuck
for i in range(NELEMENTS):
lookup[i]=inputs[i]
# data.shape =((5000,NELEMENTS))
for i in range(data.shape[0]):
for j in range(data.shape[1]):
do_something(lookup[j,data[i,j]])
If I understand correctly, there are at least 2 ways of doing what you want:
1) Create a 2-dimensional numpy array, where the size of the 2nd dimension is fixed by the largest of your input arrays. This will waste some space, but is easy, and efficient. You can use the zeros function to create a 2-dim array full of zeros, and then just populate the required entries. This is shown below as Option 1.
2) Create a nested numpy array, where lookup2[i] is a 1-dim numpy array of size defined by the number of elements in input[i]. This is also straight-forward, but less efficient, as the internal arrays are stored as generic Python objects.
inputs = [ [1] ,[2,3,4], [5,6], [7,8,9,10,11,12]]
NELEMENTS=len(inputs)
# Option 1: create 2-dim numpy array full of zeros, and only populate necessary
# parts
maxInputSize = max( [len(x) for x in inputs] )
cdef np.ndarray[double,ndim=2] lookup = np.zeros( (NELEMENTS, maxInputSize) )
for i in range(NELEMENTS):
for j in range(len(inputs[i])):
lookup[i][j] = inputs[i][j]
# Option 2: create nested numpy array
cdef np.ndarray[object, ndim=1] lookup2 = np.empty( (NELEMENTS,), dtype='object' )
for i in range(NELEMENTS):
nInputs = len(inputs[i])
lookup2[i] = np.zeros(nInputs)
for j in range(nInputs):
lookup2[i][j] = inputs[i][j]
I have a function toWords which converts a integer into a word
e.g. toWords(500, tableWords) gives fivehundred
I have an array of numbers h = (1..999).to_a, and I want to go through this array and convert each number into a word and store it in a new array. My current attempt to do this is:
h = (1..999).to_a
Lh = h.each do |i| toWords(i, tableWords) end
However, the contents of Lh is simply the integers from 1 to 999 and not the output of my toWords function. How do I do this? I'm thinking of something along the lines of sapply in R.
Even better is if my new array Lh can have two columns, the first column containing the integers in number format, and the second column would be the corresponding number in words.
Thank you!
To get your two columns, you can do the following
(1..999).map {|x| [x, toWords(x, tableWords)]}
As per Cicada's comment, the answer is:
Lh = h.map{|x| toWords(x, tableWords)}