How to raise an array in power while broadcasting it? - python

i have to following problem: I need a 1d-string with equaly distributed numbers on a LOG-scale. To eb precise: 1,2,3,4,5,6,7,8,9,10,20,30,40...,100,200,300,... and so on. This can go up to 10^9, so typing is not an option ;)
my code so far is the following:
ome = np.linspace(1,9,9).reshape(9,1)
pow = np.linspce(0,5,6).reshape(1,6)
logome = ome*(10**pow)
but this not working and i don't know how to proceed... any suggestions?
okay, i figured some way out, if anybody is interested:
ome = np.linspace(1,9,9).reshape(1,9)
pow = np.linspce(0,5,6)
pow = np.power(10,pow).reshape(6,1)
logome = ome*pow
logome.reshape(54)
et voila :)

To get your desired output, I'd probably do something like this:
>>> (np.arange(1, 10) * 10**np.arange(9)[:,None]).flatten()
array([ 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 20, 30,
40, 50, 60, 70, 80, 90,
100, 200, 300, 400, 500, 600,
700, 800, 900, 1000, 2000, 3000,
4000, 5000, 6000, 7000, 8000, 9000,
10000, 20000, 30000, 40000, 50000, 60000,
70000, 80000, 90000, 100000, 200000, 300000,
400000, 500000, 600000, 700000, 800000, 900000,
1000000, 2000000, 3000000, 4000000, 5000000, 6000000,
7000000, 8000000, 9000000, 10000000, 20000000, 30000000,
40000000, 50000000, 60000000, 70000000, 80000000, 90000000,
100000000, 200000000, 300000000, 400000000, 500000000, 600000000,
700000000, 800000000, 900000000])
where the second term works like this:
>>> np.arange(5)
array([0, 1, 2, 3, 4])
>>> np.arange(5)[:, None]
array([[0],
[1],
[2],
[3],
[4]])
>>> 10**np.arange(5)[:, None]
array([[ 1],
[ 10],
[ 100],
[ 1000],
[10000]])
You might also be interested in np.logspace. BTW, note that this array isn't equally distributed on a log-scale.

Related

How to add Element to a List in Python inside another list

I'm trying to add "7000" element to this list [10, 20, [300, 400, [5000, 6000, ], 500], 30, 40]
I want to add 7000 after 6000 on this list … already try some methods to add this element
Use the append() method to update an list in place
>>> x = [10, 20, [300, 400, [5000, 6000], 500], 30, 40]
>>> x[2][2].append(7000)
>>> x
[10, 20, [300, 400, [5000, 6000, 7000], 500], 30, 40]
You can use the append() method on any list, no matter how nested it is.
your list:- lst=[10, 20, [300, 400, [5000, 6000, ], 500], 30, 40]
well see in your list at index position 2 there is another list
that list:-[300, 400, [5000, 6000, ], 500]
in the above list there is another list at index 2 i.e [5000, 6000, ]
so use append() method in this code:-
lst[2][2].append(7000)

Adding items from one list to specific items of another list

Consider two lists:
a = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000]
b = [-10, 20, -88, 15, 10, -6, 10, 10]
I wish to create a third list where each negative value from list b is replace with the corresponding (same index) item from list a. And then consecutively add the following positive numbers in list b to that replaced value (from list a), until the next negative number.
To clarify, the resulted list in the above case should be:
c = [1000, 1020, 3000, 3015, 3025, 6000, 6010, 6020]
my (working) code so far:
a = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000]
b = [-10, 20, -88, 15, 10, -6, 10, 10]
c = []
for i in range(len(b)):
if b[i] < 0:
c.append(a[i])
else:
c.append(c[-1]+b[i])
Is there a way to do so without a for loop? the lists can get very lengthy.
Any help would be appreciated :)
I used zip to go through both of the list, in this case with the assumption that both lengths are equal. Should be able to work for most cases as long it is.
a = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000]
b = [-10, 20, -88, 15, 10, -6, 10, 10]
c = []
old_val = 0
for value_a,value_b in zip(a,b):
print(value_b)
if value_b < 0:
c.append(value_a)
old_val = value_a
else:
old_val += value_b
c.append(old_val)
#[1000, 1020, 3000, 3015, 3025, 6000, 6010, 6020]

Subtracting columns from a numpy array

This question is a follow-up of a previous post of mine:
Multiply each column of a numpy array with each value of another array.
Suppose i have the following arrays:
In [252]: k
Out[252]:
array([[200, 800, 400, 1600],
[400, 1000, 800, 2000],
[600, 1200, 1200,2400]])
In [271]: f = np.array([[100,50],[200,100],[300,200]])
In [272]: f
Out[272]:
array([[100, 50],
[200, 100],
[300, 200]])
How can i subtract f from k to obtain the following?
In [252]: g
Out[252]:
array([[100, 750, 300, 1550],
[200, 900, 600, 1900],
[300, 1000, 900,2200]])
Ideally, i would like to make the subtraction in as fewer steps as possible and in concert with the solution provided in my other post, but any solution welcome.
You can use np.tile, like this:
In [1]: k - np.tile(f, (1, 2))
Out[1]:
array([[ 100, 750, 300, 1550],
[ 200, 900, 600, 1900],
[ 300, 1000, 900, 2200]])
Also, if you happen to know for sure that each dimension of f evenly divides the corresponding dimension of k (which I assume you must, for your desired subtraction to make sense), then you could generalize it slightly:
In [2]: k - np.tile(f, np.array(k.shape) // np.array(f.shape))
Out[2]:
array([[ 100, 750, 300, 1550],
[ 200, 900, 600, 1900],
[ 300, 1000, 900, 2200]])
You can reshape k, to fit f in two dimensions, and use broadcasting:
>>> g = (k.reshape(f.shape[0], -1, f.shape[1]) - f[:, None, :]).reshape(k.shape)
array([[ 100, 750, 300, 1550],
[ 200, 900, 600, 1900],
[ 300, 1000, 900, 2200]])

How to add an item to the top of the array in Python? [duplicate]

This question already has answers here:
Append integer to beginning of list in Python [duplicate]
(10 answers)
Closed 7 years ago.
I have:
[10, 20, 30, 40, 1000, 5000, 0, 5000]
I need:
[-100,10, 20, 30, 40, 1000, 5000, 0, 5000]
How to add an item to the top of the array in Python 3.4?
Try using list.insert(index, element)
listA = [10, 20, 30, 40, 1000, 5000, 0, 5000]
listA.insert(0, -100)
Below code will do..
a = [10, 20, 30, 40, 1000, 5000, 0, 5000]
a.insert(0,-100)
print(a)
Easy, you should use the insert method.
alist=[1,2,3,4,5,6,7]
# to Add
alist.insert(0, 0)
print(alist)
The result will be
#/usr/bin/python3.4 test.py
[0, 1, 2, 3, 4, 5, 6, 7]

Greedy algorithm in Python

I want c in plunder(aList, c) to equal 0.
List = [('Gold', 10, 500), ('Silver', 5, 200), ('Diamond', 2, 2000), ('Platinum', 20, 1000)]
aList = sorted(List, key = lambda x : x[2]) # sort the list above
Gives me the sorted list based on the 3rd value of each tuple. So I get:
[('Silver', 5, 200), ('Gold', 10, 500), ('Platinum', 20, 1000), ('Diamond', 2, 2000)]
I am trying to get the plunder(aList, c) to keep subtracting the middle values of each tuple (2, 20, 10, 5) from c until c = 0.
Here is my code:
List = [('Gold', 10, 500), ('Silver', 5, 200), ('Diamond', 2, 2000), ('Platinum', 20, 1000)]
aList = sorted(List, key = lambda x : x[2]) # sort the list above
def plunder(aList, c):
aList[-1] = list(aList[-1])
i = aList[-1]
r = 0
if c > 0 and i[1] != 0:
c -= 1
i[1] -=1
r += 1
return plunder(aList, c-r)
elif c == 0:
pass
print('Done')
else:
return plunder(aList[:-1], c-r)
plunder(aList, 10)
But when I run it, it prints done and the new list is:
[('Silver', 5, 200), ('Gold', 10, 500), ('Platinum', 20, 1000), ['Diamond', 0, 2000]]
and also when I type c in the python shell, it tells me that c is not defined. How could I fix these issues?
So if the c value is 10. My expected output would be:
[('Silver', 5, 200), ('Gold', 10, 500), ['Platinum', 12, 1000], ['Diamond', 0, 2000]]
I subtracted as many diamonds as I could from the 10 (10 - 2 = 8) so 0 diamonds were left. Then I subtracted 8 from 20 platinums and the weight of the platinums changed to 12 (since I took 8 platinums. And now my c ('capacity') is 0. 2 diamonds + 8 platinums = 10 (which was my c).
The main problem is that you are relying on Python's pass by reference for lists to modify the list in place.
That works fine initially, but when you reach
plunder(aList[:-1], c-r)
Python creates a copy of the list and proceeds to modify that copy. Thus your original list remains unchanged after Diamonds are exhausted (you hit the else part).
Note that you can see this behaviour in your printed aList as only last entry is a list and all other are tuples.
[
('Silver', 5, 200),
('Gold', 10, 500),
('Platinum', 20, 1000),
['Diamond', 0, 2000] #Only list
]
If you add a print alist[-1] statement to the function, you can see it even more clearly.
['Diamond', 2, 2000]
['Diamond', 1, 2000]
['Diamond', 0, 2000]
['Platinum', 20, 1000]
['Platinum', 19, 1000]
['Platinum', 18, 1000]
['Platinum', 17, 1000]
['Platinum', 16, 1000]
['Platinum', 15, 1000]
['Platinum', 14, 1000]
['Platinum', 13, 1000]
['Platinum', 12, 1000]
So your algorithm does work but as you have no way of keeping the result, it does not (fully) affect your original list.
Here is what I think is a more simple approach. Simply iterate through the available treasure and grab as much as you can/need from each one.
def demo():
units_to_plunder = 10
treasure = new_treasure_pile()
plundered_units = plunder_units(treasure, units_to_plunder)
print treasure
print plundered_units
units_to_plunder = 1000
treasure = new_treasure_pile()
plundered_units = plunder_units(treasure, units_to_plunder)
print treasure
print plundered_units
def plunder_units(treasure, total_plunder_units):
treasure_sorted = list(sorted(treasure, key=lambda t: t[2], reverse=True))
plundered = list()
for treasure_type in treasure_sorted:
# stop condition when desired units taken
if total_plunder_units <= 0:
break
t_units_to_take = min(total_plunder_units, treasure_type[1])
# update the 3 moving parts
treasure_type[1] -= t_units_to_take
plundered.append([treasure_type[0], t_units_to_take, treasure_type[2]])
total_plunder_units -= t_units_to_take
return plundered
def new_treasure_pile():
return [['Gold', 10, 500],
['Silver', 5, 200],
['Diamond', 2, 2000],
['Platinum', 20, 1000]]
if __name__ == '__main__':
demo()
Output for c=10 (I think as you expect)
[['Gold', 10, 500], ['Silver', 5, 200], ['Diamond', 0, 2000], ['Platinum', 12, 1000]]
[['Diamond', 2, 2000], ['Platinum', 8, 1000]]
Output for c=1000 (take it all)
[['Gold', 0, 500], ['Silver', 0, 200], ['Diamond', 0, 2000], ['Platinum', 0, 1000]]
[['Diamond', 2, 2000], ['Platinum', 20, 1000], ['Gold', 10, 500], ['Silver', 5, 200]]

Categories