我有一个包含一列键和其他一些列的数据框。我想合并(sum)数据帧的特定行。应该将哪些行相加在一起由字典提供。此映射由{key:[list of other keys]}的字典提供。
具体来说,这是一些示例代码:
data = [('A', 4, 10),
('B', 7, 10),
('C', 3, 9)]
labels = ['Key','Col1','Col2']
mydf = pd.DataFrame(data,columns=labels)
idx_grouping_dict = { 'A' : ['C'], 'B' : ['A'], 'C' : ['A', 'B']}
desired_result = pd.DataFrame(
[('A', 7, 19),
('B', 11, 20),
('C', 14, 29)], columns=labels)
这里,索引为' A'被添加到具有索引' C'的行,具有索引的行' B'被添加到具有索引' A'的行,以及具有索引' C'的行被添加到两行' A'和' B'。
我确定有办法做到这一点!也许形成某种临时数据帧并使用聪明的内部或外部联接?我很难过。
答案 0 :(得分:4)
您可以使用键和值作为两个单独的列从字典创建数据框,将其与mydf
连接,然后按键列(来自原始字典)和总和列分组:
pd.DataFrame([(g, k) for g, ks in idx_grouping_dict.items() for k in ks + [g]],
columns=["GKey", "Key"]).merge(mydf).groupby("GKey", as_index=False).sum()
#GKey Col1 Col2
#0 A 7 19
#1 B 11 20
#2 C 14 29
keydf = pd.DataFrame([(g, k) for g, ks in idx_grouping_dict.items() for k in ks + [g]], columns=["GKey", "Key"])
keydf
#GKey Key
#0 C A
#1 C B
#2 C C
#3 B A
#4 B B
#5 A C
#6 A A
keydf.merge(mydf)
#GKey Key Col1 Col2
#0 C A 4 10
#1 B A 4 10
#2 A A 4 10
#3 C B 7 10
#4 B B 7 10
#5 C C 3 9
#6 A C 3 9
keydf.merge(mydf).groupby('GKey', as_index=False).sum()
#GKey Col1 Col2
#0 A 7 19
#1 B 11 20
#2 C 14 29
另一种选择:
val_df = mydf.set_index("Key")
pd.DataFrame.from_dict({g: val_df.loc[[g] + ks].sum() for g, ks in idx_grouping_dict.items()}, orient="index")
# Col1 Col2
#A 7 19
#B 11 20
#C 14 29
时序:
%%timeit
val_df = mydf.set_index("Key")
pd.DataFrame.from_dict({g: val_df.loc[[g] + ks].sum() for g, ks in idx_grouping_dict.items()}, orient="index")
# 100 loops, best of 3: 2.51 ms per loop
%timeit pd.DataFrame([(g, k) for g, ks in idx_grouping_dict.items() for k in ks + [g]], columns=["GKey", "Key"]).merge(mydf).groupby("GKey", as_index=False).sum()
# 100 loops, best of 3: 3.22 ms per loop
答案 1 :(得分:3)
这是一个(略微)较慢的解决方案,它涉及首先转置数据帧,然后在转置它之前执行列式求和。
# https://stackoverflow.com/a/45332338/4909087
In [457]: temp = mydf.T.rename_axis(None, axis=1)
In [456]: pd.DataFrame({k : temp[[k]].join(temp[[i for i in v]]).agg('sum', axis=1) for k, v in idx_grouping_dict.items()}).T
Out[456]:
Col1 Col2
A 7 19
B 11 20
C 14 29
答案 2 :(得分:1)
我的解决方案基于Dataframe
..
idx_grouping_dict = { 'A' : ['C'], 'B' : ['A'], 'C' : ['A', 'B']}
s = pd.DataFrame(pd.Series(idx_grouping_dict, name='Va'))
s.apply(lambda x: x['Va'].append(x.name), axis=1)
Temp_unnest = pd.DataFrame([[i, x]
for i, y in s['Va'].apply(list).iteritems()
for x in y], columns=list('IV'))
data = [('A', 4, 10),
('B', 7, 10),
('C', 3, 9)]
labels = ['Key','Col1','Col2']
mydf = pd.DataFrame(data,columns=labels)
Temp_unnest=Temp_unnest.merge(mydf,left_on='V',right_on='Key',how='left')
Temp_unnest.groupby('I').sum()
Col1 Col2
I
A 7 19
B 11 20
C 14 29