将列值分组到字典中

时间:2018-04-19 17:21:13

标签: python pandas dictionary dataframe

假设我有一个以下结构的数据框:

   Name   Desc   Group ConditionType ConditionName
0  job1  desc1  group1            in         cond1
1  job1  desc1  group1            in         cond2
2  job1  desc1  group1           out         cond1
3  job2  desc2  group1            in         cond1
4  job2  desc2  group1            in         cond2
5  job2  desc2  group1            in         cond3

对于上下文,它是两个表的完全连接;一个包含NameDescGroup列,另一个包含ConditionTypeConditionName列。表格在Name列上加入。

我想组织这个DataFrame,这样我就有了以下结构:

   Name   Desc   Group                                      Conditions
0  job1  desc1  group1    {'in': ['cond1', 'cond2'], 'out': ['cond1']}
1  job2  desc2  group1  {'in': ['cond1', 'cond2', 'cond3'], 'out': []}

我正在寻找一种更快的方法(可能使用groupby()apply()),但不知道从哪里开始。 For-loop非常慢,因为原始表超过100000条记录。

这里是用于实例化初始表和我寻求的结果的代码:

table = [['job1', 'desc1', 'group1', 'in', 'cond1'],
         ['job1', 'desc1', 'group1', 'in', 'cond2'],
         ['job1', 'desc1', 'group1', 'out', 'cond1'],
         ['job2', 'desc2', 'group1', 'in', 'cond1'],
         ['job2', 'desc2', 'group1', 'in', 'cond2'],
         ['job2', 'desc2', 'group1', 'in', 'cond3']]

result = [['job1', 'desc1', 'group1', {'in': ['cond1', 'cond2'], 'out': ['cond1']}],
          ['job2', 'desc2', 'group1', {'in': ['cond1', 'cond2', 'cond3'], 'out': []}]]

table_df = pd.DataFrame(table, columns=['Name', 'Desc', 'Group', 'ConditionType', 'ConditionName'])
result_df = pd.DataFrame(result, columns=['Name', 'Desc', 'Group', 'Conditions'])

1 个答案:

答案 0 :(得分:2)

将采用pandas方式,但这是通过行迭代和collections.defaultdict的直观方式。

请注意,您可能希望进行一些小的调整(重置索引,添加空字典项)。

groupby方法必然更快。您应该使用您的数据进行测试。为了提高性能,请使用df.itertuples代替df.iterrows

from collections import defaultdict

d = defaultdict(lambda: defaultdict(list))

for idx, row in df.iterrows():
    d[(row.Name, row.Desc, row.Group)][row.ConditionType].append(row.ConditionName)

df['Conditions'] = df.set_index(['Name', 'Desc', 'Group']).index.map(d.get)

df = df.loc[:, ['Name', 'Desc', 'Group', 'Conditions']]\
       .drop_duplicates(subset=['Name', 'Desc', 'Group'])

print(df)

#    Name   Desc   Group                                    Conditions
# 0  job1  desc1  group1  {'in': ['cond1', 'cond2'], 'out': ['cond1']}
# 3  job2  desc2  group1           {'in': ['cond1', 'cond2', 'cond3']}