Detect specific value change in Pandas DataSeries - python

I want to detect a specific change of the value of a DataSeries in Pandas.
Given I got a DataSeries of the following Format:
ds = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 1, 'f': 5, 'g': 2}
With DataSeries built in diff(1) function I am able to detect a value change and how big it was. Is it possible to only get the occurances where the value changes from 4 to 1?

Compare original values by 4 and shifted by 1 and for count Trues use sum:
ds = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 1, 'f': 5, 'g': 2}
s = pd.Series(ds)
s = (s.eq(4) & s.shift(-1).eq(1)).sum()
print (s)
1
Details:
print (s.eq(4) & s.shift(-1).eq(1))
a False
b False
c False
d True
e False
f False
g False
dtype: bool

Related

How to update a dictionary at specific positions? [duplicate]

This question already has answers here:
How to insert key-value pair into dictionary at a specified position?
(8 answers)
Closed 1 year ago.
I have dictionary like below:
data = {'a': 1, 'c': 2, 'd': 3}
Is there any way to update my above dictionary after particular key? For example you want to add 'b':4 after 'a':1, and at the end add 'E':6 — so final output map should look like below:
data = {'a': 1, 'b':4, 'c': 2, 'd': 3, 'E':6}
I have gone through some documentation but I did not find any reference where we can update dictionary at particular position.
May this solve your problem and the return value is also dict not list
import operator
data = {'a': 1, 'c': 2, 'd': 3}
data['b'] = 4
data['e'] = 6
sorted_d = dict(sorted(data.items(), key=operator.itemgetter(0)))
Output
{'a': 1, 'b': 4, 'c': 2, 'd': 3, 'e': 6}
For example, you updated your data dict with like this below:
data = {'a': 1, 'd': 3, 'c': 2, 'e':6, 'b':4}
Then you can do something like this:
# x[0] is referring to the key here. if you want to sort based on the value
# then it will be x[1]
sort_orders = dict(sorted(data.items(), key=lambda x: x[0]))
which will give:
{'a': 1, 'b': 4, 'c': 2, 'd': 3, 'e': 6}
Note: this might be case sensitive while sorting the order.

Python: how to create a parameter grid with dynamic number of parameters

Suppose that the range of parameters of interest are given a dictionary that contains the range for each parameter of interest:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
The goal is to extract every parameter configuration on this grid. In the example above, there are 4 such, corresponding to 2 values of a, and two values of b:
G1 = {'a': 1, 'b': 3, 'c': 1 }
G2 = {'a': 2, 'b': 3, 'c': 1 }
G3 = {'a': 1, 'b': 3, 'c': 2.5 }
G4 = {'a': 2, 'b': 3, 'c': 2.5 }
It's straightforward to write two nested for loops to produce all such configurations, it becomes less trivial how to do it for a general case, when there are a variable number of lists in G.
The only solution that comes to my mind is to create a multi-index vector vec=[0,0] which is as long as the number of parameters, and increment to iterate over all possible configurations: [0,0] -> [1,0] -> [0,1] -> [1,1]:
G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
def get_configs(G):
keys = list(G.keys())
lists = list(G.values())
sizes = [len(l) for l in lists]
num_confs = np.prod(sizes)
index = [0]*(len(G)+1)
configs = []
while len(configs)<num_confs:
configs.append( {keys[i]: lists[i][index[i]] for i in range(len(G))})
index[0] += 1
cur = 0
while len(configs)<num_confs and index[cur]>=sizes[cur]:
index[cur]=0
cur += 1
index[cur] += 1
return configs
configs = get_configs(G)
print(configs)
However, the solution seems a bit over-complicated and ugly. Is there a clean solution using python?
Here is a generalizable implementation using itertools.product:
from itertools import product
def dict_configs(d):
for vcomb in product(*d.values()):
yield dict(zip(d.keys(), vcomb))
Usage:
>>> G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
>>> for config in dict_configs(G):
... print(config)
...
{'a': 1, 'b': 3, 'c': 1}
{'a': 1, 'b': 3, 'c': 2.5}
{'a': 2, 'b': 3, 'c': 1}
{'a': 2, 'b': 3, 'c': 2.5}

Add two dictionaries in python and subtract result from another

I have three dictionaries:
X = {'a':2, 'b':3,'e':4}
Y = {'c':3, 'b':4,'a':5, 'd':7}
Z = {'c':8, 'b':7,'a':9, 'e':10,'f':10}
I want to add elements of X and Y if they are present in both dicts and then subtract them from z i.e. Z-X+Y
How can I do that ?
expected result:
res = {'a':2,'b':0,'c':5,'d':7,'e':6,'f':10}
What I tried:
from collections import Counter
xy = Counter(X) + Counter(Y)
res = Counter(Z) - xy
which return:
Counter({'c': 5, 'a': 2, 'e': 6, 'f': 10})
as you can see b and d are missing from my attempt
Your expected result is actually an operation of symmetric difference in terms of sets, but since collections.Counter doesn't support such an operation, you can emulate it with:
xy = Counter(X) + Counter(Y)
z = Counter(Z)
res = z - xy | xy - z
res becomes:
Counter({'f': 10, 'd': 7, 'e': 6, 'c': 5, 'a': 2})
But if you do want keys with value of 0, which Counter would hide from its output, you would have to iterate through a union of the keys of the 3 dicts:
{k: res.get(k, 0) for k in {*X, *Y, *Z}}
This returns:
{'a': 2, 'd': 7, 'e': 6, 'b': 0, 'f': 10, 'c': 5}

How to multiple values of keys with different numbers in dictionary?

Im trying to multiple some values from dictionary
example
price_list = {'a': 3, 'b': 2, 'c': 5, 'd': 10}
when i type
total=sum(price_list.values())
print("Total sum is ",total)
it result 20
But now i want to multiple a with 3, b with 5, c with 2 and d with 3 and my desired output to be 59. What is easiest way to do that?
Assuming your numbers are stored in the list, iterate through the values, and multiply with your required number like so
price_dict = {'a': 3, 'b': 2, 'c': 5, 'd': 10}
numbers_dict = {'a': 3, 'b': 5, 'c': 2, 'd': 3}
result = 0
for key, value in price_dict.items():
result += numbers_dict[key] * value
print(result)
#59
You can just perform operations on the dictionary item like you would any other variable:
# multiply 'a' by 3
price_list['a'] *= 3
Try this:
price_list = {'a': 3, 'b': 2, 'c': 5, 'd': 10}
numbers = [3,5,2,3]
for k,n in list(zip(price_list, numbers)):
price_list[k] *= n
then the price list will change, you can use sum as you did to calculate the result.

Iterate over X dictionary items in Python

How can I iterate over only X number of dictionary items? I can do it using the following bulky way, but I am sure Python allows a more elegant way.
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
x = 0
for key in d:
if x == 3:
break
print key
x += 1
If you want a random sample of X values from a dictionary you can use random.sample on the dictionary's keys:
from random import sample
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
X = 3
for key in sample(d, X):
print key, d[key]
And get output for example:
e 5
c 3
b 2

Categories