Related
b = [[2021, 55, -0.65, 7.61, 10.65, 41.37, 3.39, 12.25, -10.14, 7.61, 8.84],
[2022, 56, 3.0, -0.13, 8.84, 27.25, -0.48, 2.54, 12.43, 7.56, 3.37]]
I want to divide elements [2:10] of each sub list in b by 100. Result expected:
a = [2021, 55, -0.0065, 0.0761, 0.1065, 0.4137, 0.0339, 0.1225, -0.1014, 0.0761, 0.0884], etc
I've tried:
a = [item[2:10] /100 for item in b] Also tried: a = [item[2:10] / 100 for item in x] for x in b]
The first one gives "unsupported operand type for /: list and int". Second one gives "int object not subscriptable"
A minor error in your list comprehension, you were slicing in the wrong place. What you need to do is this:
a = [x[:2] + [item / 100 for item in x[2:]] for x in b]
print(a)
Output:
[[2021, 55, -0.006500000000000001, 0.0761, 0.1065, 0.41369999999999996, 0.0339, 0.1225, -0.1014, 0.0761, 0.08839999999999999], [2022, 56, 0.03, -0.0013, 0.08839999999999999, 0.2725, -0.0048, 0.0254, 0.1243, 0.0756, 0.0337]]
Without list comprehension
In [12]: b = [[2021, 55, -0.65, 7.61, 10.65, 41.37, 3.39, 12.25, -10.14, 7.61, 8
...: .84],
...: [2022, 56, 3.0, -0.13, 8.84, 27.25, -0.48, 2.54, 12.43, 7.56, 3.37
...: ]]
...:
In [13]: for i in range(len(b)):
...: if len(b[i]) >= 10:
...: for j in range(2,10):
...: b[i][j] = b[i][j]/100
output:
[[2021,
55,
-0.006500000000000001,
0.0761,
0.1065,
0.41369999999999996,
0.0339,
0.1225,
-0.1014,
0.0761,
8.84],
[2022,
56,
0.03,
-0.0013,
0.08839999999999999,
0.2725,
-0.0048,
0.0254,
0.1243,
0.0756,
3.37]]
No need to take slices out first... change your list-comprehension to:
b = [[2021, 55, -0.65, 7.61, 10.65, 41.37, 3.39, 12.25, -10.14, 7.61, 8.84],
[2022, 56, 3.0, -0.13, 8.84, 27.25, -0.48, 2.54, 12.43, 7.56, 3.37]]
res = [[item / 100 if 2 <= i < 10 else item for i, item in enumerate(lst)] for lst in b]
print(res)
Output:
[[2021, 55, -0.006500000000000001, 0.0761, 0.1065, 0.41369999999999996, 0.0339, 0.1225, -0.1014, 0.0761, 8.84], [2022, 56, 0.03, -0.0013, 0.08839999999999999, 0.2725, -0.0048, 0.0254, 0.1243, 0.0756, 3.37]]
res = [x[:2] + [x[i]/100 for i in range(len(x)) if i > 1] for x in b]\
print(res)
How can I find the index position of items in a list which satisfy a certain condition?
Like suppose, I have a list like:
myList = [0, 100, 335, 240, 300, 450, 80, 500, 200]
And the condition is to find out the position of all elements within myList which lie between 0 and 300 (both inclusive).
I am expecting the output as:
output = [0, 1, 3, 4, 6, 8]
How can I do this in pandas?
Also, how to find out the index of the maximum element in the subset of elements which satisfy the condition? Like, in the above case, out of the elements which satisfy the given condition 300 is the maximum and its index is 4. So, need to retrieve its index.
I have been trying many ways but not getting the desired result. Please help, I am new to the programming world.
You can try this,
>>> import pandas as pd
>>> df = pd.DataFrame({'a': [0, 100, 335, 240, 300, 450, 80, 500, 200]})
>>> index = list(df[(df.a >= 0) & (df.a <= 300)].index)
>>> df.loc[index,].idxmax()
a 4
dtype: int64
or using the list,
>>> l = [0, 100, 335, 240, 300, 450, 80, 500, 200]
>>> index = [(i, v) for i, v in enumerate(l) if v >= 0 and v <= 300]
>>> [t[0] for t in index]
[0, 1, 3, 4, 6, 8]
>>> sorted(index, key=lambda x: x[1])[-1][0]
4
As Grzegorz Skibinski says, if we use numpy to get rid of many computations,
>>> import numpy as np
>>> l = [0, 100, 335, 240, 300, 450, 80, 500, 200]
>>> index = np.array([[i, v] for i, v in enumerate(l) if v >= 0 and v <= 300])
>>> index[:,0]
array([0, 1, 3, 4, 6, 8])
>>> index[index.argmax(0)[1]][0]
4
You can use numpy for that purpose:
import numpy as np
myList =np.array( [0, 100, 335, 240, 300, 450, 80, 500, 200])
res=np.where((myList>=0)&(myList<=300))[0]
print(res)
###and to get maximum:
res2=res[myList[res].argmax()]
print(res2)
Output:
[0 1 3 4 6 8]
4
[Program finished]
This is between in pandas:
myList = [0, 100, 335, 240, 300, 450, 80, 500, 200]
s= pd.Series(myList)
s.index[s.between(0,300)]
Output:
Int64Index([0, 1, 3, 4, 6, 8], dtype='int64')
I want to swap elements between two array starting from a particular array index value keeping other values prior to the array index intact.
import numpy as np
r = np.array([10, 20, 30, 40, 50, 60])
p = np.array([70, 80, 90, 100, 110, 120])
t = []
for i in range(len(r)):
for j in range(len(p)):
if i >= 3 and j >= 3:
t.append(p[j])
p[j] = r[i]
for k in t:
r[i] = k
The above code does the task but the values are in reverse order.
The value that I want in array p after swapping is:
[70, 80, 90, 40, 50, 60]
and the value that i want in array r after swapping is:
[10, 20, 30, 100, 110, 120]
But in array p I am getting:
[70, 80, 90, 60, 50, 40]
and in array r I am getting:
[10, 20, 30, 120, 110, 100]
I don't know what is wrong with the code.
import numpy as np
r = np.array([10, 20, 30, 40, 50, 60])
p = np.array([70, 80, 90, 100, 110, 120])
for i in range(len(r)):
if (i>=3):
p[i],r[i] = r[i],p[i]
Above code will do the work for you. You don't need to run two for loop and t array if I understand your problem right. All you want is to swap at some indexes. You can just swap at those indexes as above no need of a temporary array t.
You can achieve the same without looping:
r = np.array([10, 20, 30, 40, 50, 60])
p = np.array([70, 80, 90, 100, 110, 120])
i = 3
temp = p[i:].copy()
p[i:] = r[i:]
r[i:] = temp
Now:
>>> p
array([70, 80, 90, 40, 50, 60])
>>> r
array([ 10, 20, 30, 100, 110, 120])
You can copy a slice of one array on to the other:
In [113]: r = np.array([10, 20, 30, 40, 50, 60])
...: p = np.array([70, 80, 90, 100, 110, 120])
...:
In [114]: t = p.copy()
In [115]: t[3:]=r[3:]
In [116]: t
Out[116]: array([70, 80, 90, 40, 50, 60])
You could also join slices:
In [117]: np.concatenate((p[:3], r[3:]))
Out[117]: array([70, 80, 90, 40, 50, 60])
Those answers create a new array. I think that's clearer than doing an inplace swap. But here's how I'd do the swap
In [128]: temp = r[3:].copy()
In [129]: r[3:]=p[3:]
In [130]: p[3:]=temp
In [131]: r
Out[131]: array([ 10, 20, 30, 100, 110, 120])
In [132]: p
Out[132]: array([70, 80, 90, 40, 50, 60])
I use copy in temp because otherwise a slice produces a view, which will get modified in the next copy. That issue has come up recently when swapping rows of a 2d array.
With lists the swapping is easier - because r[3:] makes a copy.
In [139]: r=r.tolist()
In [140]: p=p.tolist()
In [141]: temp = r[3:]
In [142]: r[3:], p[3:] = p[3:], r[3:]
In [143]: r
Out[143]: [10, 20, 30, 100, 110, 120]
In [144]: p
Out[144]: [70, 80, 90, 40, 50, 60]
Was looking for a way to get the list of a partial row.
Name x y r
a 9 81 63
a 98 5 89
b 51 50 73
b 41 22 14
c 6 18 1
c 1 93 55
d 57 2 90
d 58 24 20
So i was trying to get the dictionary as follows,
di = {a:{0: [9,81,63], 1: [98,5,89]},
b:{0:[51,50,73], 1:[41,22,14]},
c:{0:[6,18,1], 1:[1,93,55]},
d:{0:[57,2,90], 1:[58,24,20]}}
Use groupby with custom function for count lists, last convert output Series to_dict:
di = (df.groupby('Name')['x','y','r']
.apply(lambda x: dict(zip(range(len(x)),x.values.tolist())))
.to_dict())
print (di)
{'b': {0: [51, 50, 73], 1: [41, 22, 14]},
'a': {0: [9, 81, 63], 1: [98, 5, 89]},
'c': {0: [6, 18, 1], 1: [1, 93, 55]},
'd': {0: [57, 2, 90], 1: [58, 24, 20]}}
Detail:
print (df.groupby('Name')['x','y','r']
.apply(lambda x: dict(zip(range(len(x)),x.values.tolist()))))
Name
a {0: [9, 81, 63], 1: [98, 5, 89]}
b {0: [51, 50, 73], 1: [41, 22, 14]}
c {0: [6, 18, 1], 1: [1, 93, 55]}
d {0: [57, 2, 90], 1: [58, 24, 20]}
dtype: object
Thank you volcano for suggestion use enumerate:
di = (df.groupby('Name')['x','y','r']
.apply(lambda x: dict(enumerate(x.values.tolist())))
.to_dict())
For better testing is possible use custom function:
def f(x):
#print (x)
a = range(len(x))
b = x.values.tolist()
print (a)
print (b)
return dict(zip(a,b))
[[9, 81, 63], [98, 5, 89]]
range(0, 2)
[[9, 81, 63], [98, 5, 89]]
range(0, 2)
[[51, 50, 73], [41, 22, 14]]
range(0, 2)
[[6, 18, 1], [1, 93, 55]]
range(0, 2)
[[57, 2, 90], [58, 24, 20]]
di = df.groupby('Name')['x','y','r'].apply(f).to_dict()
print (di)
Sometimes it is best to minimize the footprint and overhead.
Using itertools.count, collections.defaultdict
from itertools import count
from collections import defaultdict
counts = {k: count(0) for k in df.Name.unique()}
d = defaultdict(dict)
for k, *v in df.values.tolist():
d[k][next(counts[k])] = v
dict(d)
{'a': {0: [9, 81, 63], 1: [98, 5, 89]},
'b': {0: [51, 50, 73], 1: [41, 22, 14]},
'c': {0: [6, 18, 1], 1: [1, 93, 55]},
'd': {0: [57, 2, 90], 1: [58, 24, 20]}}
I would like to have the maximum value per key in a Python dictionary.
dictionary = {"age": [25, 29], "coverage": [100, 45], "z_parameter": [23, 39]}
print(dictionary)
{'coverage': [100, 45], 'age': [25, 29], 'z_parameter': [23, 39]}
Desired output is:
{'coverage': [100], 'age': [29], 'z_parameter': [39]}
This works:
>>> d = {'coverage': [100, 45], 'age': [25, 29], 'z_parameter': [23, 39]}
>>> {key: [max(val)] for key, val in d.items()}
{'age': [29], 'z_parameter': [39], 'coverage': [100]}
>>>
dictionary = {"age": [25, 29], "coverage": [100, 45], "z_parameter": [23, 39]}
output = dict()
for key, value in dictionary.iteritems():
output[key] = max(value)
>>> print(output)
{'age': 29, 'z_parameter': 39, 'coverage': 100}
If you need your values as a list you can do wrap it in square braces when assigning the value
output[key] = [max(value)]
Using dict comprehension :
{x:[max(y)] for x, y in dictionary.iteritems()}
Output :
{'age': [29], 'z_parameter': [39], 'coverage': [100]}