如何在python3中对字典元素进行分组

时间:2019-04-04 10:28:30

标签: python python-3.x dictionary

我有一个像下面这样的字典,试图将字典与成员的进入/退出时间分组。

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
    }
}

这是我的代码,只是停留在这里。尝试在摘要中的元素后面附加member_list

summary_data = {}
for i, _ in summary.items():
    summary_data[str(i)] = {}
    member_list = []
    member_list.append(summary_data[i]['member_id'])

需要将成员的出入时间分组到新词典中

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': '-'
    },
}

2 个答案:

答案 0 :(得分:1)

您可以使用pandas

Firs按member_id对值进行排序,然后使用shift来填充相应exit_time的下一个entry_time。使用drop_duplicates删除具有相同的member_idexit_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'))

输出:

[{'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}]  

答案 1 :(得分:0)

按成员对所有数据进行分组的一个选项是使用member_id作为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'])

这将提供以下输出:

10 [('08:10 PM', 'Front'), ('11:56 PM', 'Front')]
10 [('09:05 PM', 'Gate')]
8 [('10:10 PM', 'Front')]
8 [('11:55 PM', 'Gate')]

现在,如果要按时间对进入和退出进行分组,则需要将字符串转换为datetime对象,并对列表进行排序,然后以有序的方式对它们进行交织/配对。由于AM / PM部分位于字符串的末尾,因此仅对字符串进行排序可能无法获得预期的结果。