Reputation: 27
I receive a dictionary of alerts from an API with updates on equipment condition changes, for example:
alert1 = {'equipment': 'equipment1', 'condition1': True}
alert2 = {'equipment': 'equipment1', 'condition2': True}
alert3 = {'equipment': 'equipment1', 'condition3': False}
alert4 = {'equipment': 'equipment2', 'condition1': True}
alert5 = {'equipment': 'equipment2', 'condition2': False}
alert6 = {'equipment': 'equipment3', 'condition2': False}
...
An incoming alert would trigger a function to update a "live" truth table with the expected output as:
equipment condition1 condition2 condition3
equipment1 True True False
equipment2 True False NaN
equipment3 NaN False Nan
The table should update if a new alert is received.
What is the best way to acheive this using Pandas?
Upvotes: 1
Views: 264
Reputation: 31166
Possibly a little overkill... you can append to df
and then regenerate truth table df2
as signals come in.
cl = [{'condition1': {'equipment1': True}},
{'condition2': {'equipment1': True}},
{'condition3': {'equipment1': False}},
{'condition1': {'equipment2': True}},
{'condition2': {'equipment2': False}},
{'condition2': {'equipment3': False}}]
# fully expand list / embedded dict
df = pd.json_normalize(cl, sep="-")
# bring multiple inputs together, there's only one signal per row
df2 = df.assign(foo=1).groupby("foo").agg({c:"first" for c in df.columns}).reset_index().drop(columns="foo")
# now restructure as required
df2 = df2.T.reset_index().assign(equip=lambda dfa: dfa["index"].apply(lambda r: r.split("-")[1]),
cond=lambda dfa: dfa["index"].apply(lambda r: r.split("-")[0]),
).drop(columns="index").set_index(["equip","cond"]).unstack(1).droplevel(0, axis=1).reset_index()
cond equip condition1 condition2 condition3
0 equipment1 True True False
1 equipment2 True False NaN
2 equipment3 NaN False NaN
Upvotes: 0
Reputation: 5601
same solution with create an empty dataframe first. then update df with alter_list seq by seq.
alter_list = [
{'equipment': 'equipment1', 'condition1': True},
{'equipment': 'equipment1', 'condition2': True},
{'equipment': 'equipment1', 'condition3': False},
{'equipment': 'equipment2', 'condition1': True},
{'equipment': 'equipment2', 'condition2': False},
{'equipment': 'equipment3', 'condition2': False},]
# alter_list
df = pd.DataFrame(columns=['condition1', 'condition2', 'condition3'],
index=['equipment1', 'equipment2', 'equipment3'])
for alter in alter_list:
equipment = alter.pop('equipment')
for condition,v in alter.items():
print(equipment, condition, v)
df.loc[equipment, condition] = v
result:
print(df.fillna(''))
condition1 condition2 condition3
equipment1 True True False
equipment2 True False
equipment3 False
Upvotes: 1
Reputation: 758
You can create an empty dataframe, then update it whenever you have the new data.
import pandas as pd
df = pd.DataFrame(
index=[f'equipment{i}' for i in range(1, 4)],
columns=[f'condition{i}' for i in range(1, 4)]
)
print(df)
# update whenever you have the new data
df.loc['equipment1', 'condition1'] = True
print(df)
Upvotes: 1