How to create a heatmap with condition? - python

I have the following data:
keys = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C']
values = ['111', '222', '333', '444', '555', '666', '777', '888', '222', '888', '222', '333', '999', '444', '555', '666', '777', '888']
I want to create a heatmap as follows:
mydata = pd.DataFrame({x: values, y: keys})
df_new = mydata.set_index(x)[y].astype(str).str.get_dummies().T
fig, ax = plt.subplots(figsize = (20,5))
ax = sns.heatmap(df_new, cbar=False, linewidths=.5)
plt.show()
The only issue is that the values appear as duplicated columns in a heatmap. For example, 222 appears 3 times in the heatmap. How can I push the same value to be in a single column?

Related

Iterate over rows in pandas dataframe. If blanks exist before a specific column, move all column values over

I am attempting to iterate over all rows in a pandas dataframe and move all leftmost columns within each row over until all the non null column values in each row touch. The amount of column movement depends on the number of empty columns between the first null value and the cutoff column.
In this case I am attempting to 'close the gap' between values in the leftmost columns into the column 'd' touching the specific cutoff column 'eee'. The correlating 'abc' rows should help to visualize the problem.
Column 'eee' or columns to the right of 'eee' should not be touched or moved
def moveOver():
df = {
'aaa': ['a', 'a', 'a', 'a', 'a', 'a'],
'bbb': ['', 'b', 'b', 'b', '', 'b'],
'ccc': ['', '', 'c', 'c', '', 'c'],
'ddd': ['', '', '', 'd', '', ''],
'eee': ['b', 'c', 'd', 'e', 'b', 'd'],
'fff': ['c', 'd', 'e', 'f', 'c', 'e'],
'ggg': ['d', 'e', 'f', 'g', 'd', 'f']
}
In row 1 AND 5: 'a' would be moved over 3 column index's to column 'ddd'
In row 2: ['a','b'] would be moved over 2 column index's to columns ['ccc', 'ddd'] respectively
etc.
finalOutput = {
'aaa': ['', '', '', 'a', '', ''],
'bbb': ['', '', 'a', 'b', '', 'a'],
'ccc': ['', 'a', 'b', 'c', '', 'b'],
'ddd': ['a', 'b', 'c', 'd', 'a', 'c'],
'eee': ['b', 'c', 'd', 'e', 'b', 'd'],
'fff': ['c', 'd', 'e', 'f', 'c', 'e'],
'ggg': ['d', 'e', 'f', 'g', 'd', 'f']
}
You can do this:
keep_cols = df.columns[0:df.columns.get_loc('eee')]
df.loc[:,keep_cols] = [np.roll(v, Counter(v)['']) for v in df[keep_cols].values]
print(df):
aaa bbb ccc ddd eee fff ggg
0 a b c d
1 a b c d e
2 a b c d e f
3 a b c d e f g
4 a b c d
5 a b c d e f
Explanation:
You want to consider only those columns which are to the left of 'eee', so you take those columns as stored in keep_cols
Next you'd want each row to be shifted by some amount (we need to know how much), to shift I used numpy's roll. But how much amount? It is given by number of blank values - for that I used Counter from collections.

creating a list of dictionaries from pandas dataframe

This is my df:
df = pd.DataFrame({'sym': ['a', 'b', 'c', 'x', 'y', 'z', 'q', 'w', 'e'],
'sym_t': ['tsla', 'msft', 'f', 'aapl', 'aa', 'gg', 'amd', 'ba', 'c']})
I want to separate this df into groups of three and create a list of dictionaries:
options = [{'value':'a b c', 'label':'tsla msft f'}, {'value':'x y z', 'label':'aapl aa gg'}, {'value':'q w e', 'label':'amd ba c'}]
How can I create that list? My original df has over 1000 rows.
Try groupby to concatenate the rows, then to_dict:
tmp = df.groupby(np.arange(len(df))//3).agg(' '.join)
tmp.columns = ['value', 'label']
tmp.to_dict(orient='records')
Output:
[{'value': 'a b c', 'label': 'tsla msft f'},
{'value': 'x y z', 'label': 'aapl aa gg'},
{'value': 'q w e', 'label': 'amd ba c'}]

Function to return values in dictionary

This is my dictionary:
seven_segment = {'0': {'a','c','d','e','b','f'},
'1': {'c','b'},
'2': {'a','d','e','b','g'},
'3': {'a','c','d','b','g'},
'4': {'g','c','f','b'},
'5': {'a','c','d','g','f'},
'6': {'a','c','d','e','g','f'},
'7': {'a','c','b'},
'8': {'a','c','d','e','b','g','f'},
'9': {'a','c','d','b','g','f'}}
I have a function created:
def guess_damaged(display, state, damaged):
sorted_state = ''.join(sorted(state))
sorted_damaged = ''.join(sorted(damaged))
for key in display:
templist = list(display[key])
templist = sorted(templist)
templist = ''.join(templist)
if(templist == sorted_state):
return {key for key,value in display.items() if all(sorted_damaged in value for sorted_damaged in sorted_state)}
print(guess_damaged(seven_segment, 'adeg', 'bf'))
print(guess_damaged(seven_segment, 'abed', 'cf'))
print(guess_damaged(seven_segment, '', 'abcdefg'))
My current output is shown below:
None
None
None
However, this is my desired output:
{'2'}
{'0'}
{'4', '5', '1', '8', '7', '6', '3', '0', '2', '9'}
How can I get the desired output?
Solution
I think this is what you want:
seven_segment = {'0': {'a', 'c', 'd', 'e', 'b', 'f'},
'1': {'c', 'b'},
'2': {'a', 'd', 'e', 'b', 'g'},
'3': {'a', 'c', 'd', 'b', 'g'},
'4': {'g', 'c', 'f', 'b'},
'5': {'a', 'c', 'd', 'g', 'f'},
'6': {'a', 'c', 'd', 'e', 'g', 'f'},
'7': {'a', 'c', 'b'},
'8': {'a', 'c', 'd', 'e', 'b', 'g', 'f'},
'9': {'a', 'c', 'd', 'b', 'g', 'f'}}
def guess_damaged(display, state, damaged):
return {
key
for key, value in display.items()
if set(state) == (value - set(damaged))
}
print(guess_damaged(seven_segment, 'adeg', 'bf'))
print(guess_damaged(seven_segment, 'abed', 'cf'))
print(guess_damaged(seven_segment, '', 'abcdefg'))
output:
{'2'}
{'0'}
{'7', '1', '5', '0', '9', '4', '2', '6', '3', '8'}
Explaination
set is very powerful built-in class. reference page about set
You can perform with set:
union(|)
intersect(&)
difference(-)
symmetric difference(^)
subset relations(<=, <, >, >=)
equality(==, !=)
There is no value in the seven_segment dictionary that equals 'adeg' or 'abed' or '' when sorted, so the line with "if (templist == sorted_state):" never is true

Plot a list of dictionaries using matplotlib

List =
[{'Month': '1', 'Store': 'A', 'Sales': '100'},
{'Month': '2', 'Store': 'A', 'Sales': '50'},
{'Month': '3', 'Store': 'A', 'Sales': '200'},
{'Month': '1', 'Store': 'B', 'Sales': '300'},
{'Month': '2', 'Store': 'B', 'Sales': '200'},
{'Month': '3', 'Store': 'B', 'Sales': '250'}]
I do know how to plot the basic line.
But how can I have a combined result with both data set?
Like this Expected result
This will do it. Place things in pandas simplify this - also, plot multiple line and then all will be shown on the same chart.
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(your_data)
df[['Month', 'Sales']] = df[['Month', 'Sales']].apply(pd.to_numeric, errors='coerce')
a = df[df.Store == 'A']
b = df[df.Store == 'B']
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
a.plot('Month', 'Sales', ax=ax)
b.plot('Month', 'Sales', ax=ax)
ax.grid(True)
fig.set_facecolor('white')

Extend tuples in one list using tuples from another list

I have two lists. Both lists will have the same sets of rows. I would like to add list2 columns to list1 to create one list.
list1 = [('gi1','1','2'),
('gi1','1','2'),
('gi1','1','2')]
list2 = [('a','b','c','d','e','f','g'),
('a','b','c','d','e','f','g'),
('a','b','c','d','e','f','g')]
I would like to merge these into a list that looks like this:
[('gi1','1','2','a','b','c','d','e','f','g'),
('gi1','1','2','a','b','c','d','e','f','g'),
('gi1','1','2','a','b','c','d','e','f','g')]
I would use the help of itertools.chain
>>> list1=[('gi1','1','2'),
('gi1','1','2'),
('gi1','1','2')]
>>> list2=[('a','b','c','d','e','f','g'),
('a','b','c','d','e','f','g'),
('a','b','c','d','e','f','g')]
>>> from itertools import chain
>>> [tuple(chain(x, y)) for x, y in zip(list1, list2)]
[('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g'), ('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g'), ('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g')]
If you know that both lists have the same length:
[list1[i] + list2[i] for i in range(len(list1))]
Another way to do it. Use Zip()
>>> [e1+e2 for e1,e2 in zip(list1,list2)]
[('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g'), ('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g'), ('gi1', '1', '2', 'a', 'b', 'c', 'd', 'e', 'f', 'g')]

Categories

Resources