Pandas - 将两列转换为一个新的字典列

4
我正在尝试使用Pandas将两列转换为一个列,该列是两个转换列的字典表示。
df = DataFrame({'Metrics' : [[("P", "P"), ("Q","Q")], ("K", "K"), ("Z", "Z")], 
                'Stage_Name' : ["P", "K", "Z"],  
                'Block_Name' : ["A", "B", "A"]})

基本上,我想合并 MetricsStage_Name

enter image description here

将其合并到另一个名为merged的列中,例如,第一行将是:

{'P': [('P', 'P'), ('Q', 'Q')]}

我知道如何将一行转换为字典表示,但我不确定如何在没有for循环的情况下对所有行执行此操作:
something = df.iloc[[0]].set_index('Stage_Name')['Metrics'].to_dict()
print something
Output: {'P': [('P', 'P'), ('Q', 'Q')]}

稍后我希望能够根据 Block_Name 进行聚合,因此对于合并的列,Block_NameA 的两个字典将被相加。
{'P': [('P', 'P'), ('Q', 'Q')], 'Z' : [('Z', 'Z')] }

对于Stage_NameMetrics,我会将它们附加到一个列表中,该列表如下:

grouped = df.groupby(df['Block_Name'])
df_2 = grouped.aggregate(lambda x: tuple(x))

enter image description here

有人能指点我正确的方向吗?谢谢!

2个回答

8
df['Merged'] = [{key: val} for key, val in zip(df.Stage_Name, df.Metrics)]

>>> df
  Block_Name           Metrics Stage_Name                                Merged
0          A  [(P, P), (Q, Q)]          P  {u'P': [(u'P', u'P'), (u'Q', u'Q')]}
1          B            (K, K)          K                  {u'K': (u'K', u'K')}
2          A            (Z, Z)          Z                  {u'Z': (u'Z', u'Z')}

然后您的代码将产生所需的结果:
grouped = df.groupby(df['Block_Name'])
df_2 = grouped.aggregate(lambda x: tuple(x))[['Metrics', 'Stage_Name']]


>>> df_2
                               Metrics Stage_Name
Block_Name                                       
A           ([(P, P), (Q, Q)], (Z, Z))     (P, Z)
B                            ((K, K),)       (K,)

时间:

%timeit df['Merged'] = [{key: val} for key, val in zip(df.Stage_Name, df.Metrics)]
10000 loops, best of 3: 162 µs per loop

%timeit df['merged'] = df.apply(lambda row: {row['Stage_Name']:row['Metrics']}, axis=1)
1000 loops, best of 3: 332 µs per loop

@Alexandar,这种方法是可行的,但我也试图避免使用它,因为我认为最好使用panda的内置向量化函数。 - user1157751
3
一种常见的误解。请参考上面的表现结果。 - Alexander
@Alexandar,哇,我没想到外部列表连接会更快。 - user1157751

6

如果我理解正确,那么您需要使用applylambda

In [19]:
df['merged'] = df.apply(lambda row: {row['Stage_Name']:row['Metrics']}, axis=1)
df

Out[19]:
  Block_Name           Metrics Stage_Name                           merged
0          A  [(P, P), (Q, Q)]          P  {'P': [('P', 'P'), ('Q', 'Q')]}
1          B            (K, K)          K                {'K': ('K', 'K')}
2          A            (Z, Z)          Z                {'Z': ('Z', 'Z')}

1
你只能在数据框上使用 axis=1,而不能在 Series 上使用。这个操作是按行进行的,允许你访问单独的列。 - EdChum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接