Reputation: 546
I have dictionary like the one below, trying to group the dictionary with entry/exit time of the member.
summary = {
0: {
'member_id': 10,
'entry_time': '08:10 PM',
'entry_device': 'Front',
'exit_time': None,
'exit_device': None
},
1: {
'member_id': 8,
'entry_time': '10:10 PM',
'entry_device': 'Front',
'exit_time': None,
'exit_device': None
},
2: {
'member_id': 10,
'entry_time': None,
'entry_device': None,
'exit_time': '09:05 PM',
'exit_device': 'Gate'
},
3: {
'member_id': 8,
'entry_time': None,
'entry_device': None,
'exit_time': '11:55 PM',
'exit_device': 'Gate'
},
4: {
'member_id': 10,
'entry_time': '11:56 PM',
'entry_device': 'Front',
'exit_time': None,
'exit_device': None
}
}
And this is my code, just stuck here. Trying to append the member_list
for an element in the summary.
summary_data = {}
for i, _ in summary.items():
summary_data[str(i)] = {}
member_list = []
member_list.append(summary_data[i]['member_id'])
Need to group the entry and exit times for the member in a new dictionary
summary = {
0: {
'member_id': 10,
'entry_time': '08:10 PM',
'entry_device': 'Front',
'exit_time': '09:05 PM',
'exit_device': 'Gate'
},
1: {
'member_id': 8,
'entry_time': '10:10 PM',
'entry_device': 'Front',
'exit_time': '11:55 PM',
'exit_device': 'Gate'
},
2: {
'member_id': 10,
'entry_time': '11:56 PM',
'entry_device': 'Front',
'exit_time': '-',
'exit_device': '-'
},
}
Upvotes: 2
Views: 89
Reputation: 13401
You can use pandas
for it.
Firs sort the values by member_id
then use shift
to fill next exit_time
of corresponding entry_time
. Use drop_duplicates
to drop duplicate rows which has same member_id
and exit_time
import pandas as pd
import numpy as np
df = pd.DataFrame.from_dict(summary, orient='index')
df = df.sort_values(by='member_id')
df0 = df.shift(-1)
df['exit_time'] = np.where(df['exit_time'].isnull(), df0['exit_time'], df['exit_time'])
df['exit_device'] = np.where(df['exit_device'].isnull(), df0['exit_device'], df['exit_device'])
df = df.drop_duplicates(subset=['member_id','exit_time'], keep='first')
# if you want to fill nan with `-` then use below
# df = df.fillna("-")
print(df.to_dict(orient='records'))
Output:
[{'entry_device': 'Front',
'entry_time': '10:10 PM',
'exit_device': 'Gate',
'exit_time': '11:55 PM',
'member_id': 8},
{'entry_device': 'Front',
'entry_time': '08:10 PM',
'exit_device': 'Gate',
'exit_time': '09:05 PM',
'member_id': 10},
{'entry_device': 'Front',
'entry_time': '11:56 PM',
'exit_device': nan,
'exit_time': nan,
'member_id': 10}]
Upvotes: 1
Reputation: 16505
One option to group all the data by members is to use the member_id
as the keys of a dict
:
import collections
summary = [ ...the data that you showed in the question... ]
new_summary = collections.defaultdict(
lambda: {
'entry': [],
'exit': [],
})
for elem in summary.values():
member_id = elem['member_id']
if elem['entry_time'] is not None:
new_summary[member_id]['entry'].append(
(elem['entry_time'], elem['entry_device']))
if elem['exit_time'] is not None:
new_summary[member_id]['exit'].append(
(elem['exit_time'], elem['exit_device']))
for k, v in new_summary.items():
print(k, v['entry'])
print(k, v['exit'])
This gives the following output:
10 [('08:10 PM', 'Front'), ('11:56 PM', 'Front')]
10 [('09:05 PM', 'Gate')]
8 [('10:10 PM', 'Front')]
8 [('11:55 PM', 'Gate')]
Now, if you want to group entries and exits by time then you would need to convert the strings to datetime
objects and sort the lists, and then interlace/pair them in an orderly fashion. Just sorting the strings might not give you the desired result because the AM/PM part is at the end of the string.
Upvotes: 0