【发布时间】:2021-10-05 22:27:52
【问题描述】:
我有以下带有多级列的数据框
In [1]: data = {('A', '10'):[1,3,0,1],
('A', '20'):[3,2,0,0],
('A', '30'):[0,0,3,0],
('B', '10'):[3,0,0,0],
('B', '20'):[0,5,0,0],
('B', '30'):[0,0,1,0],
('C', '10'):[0,0,0,2],
('C', '20'):[1,0,0,0],
('C', '30'):[0,0,0,0]
}
df = pd.DataFrame(data)
df
Out[1]:
A B C
10 20 30 10 20 30 10 20 30
0 1 3 0 3 0 0 0 1 0
1 3 2 0 0 5 0 0 0 0
2 0 0 3 0 0 1 0 0 0
3 1 0 0 0 0 0 2 0 0
在新列results 我想返回包含每个子集(即二级列)最大值的组合列名称
我想要的输出应该如下所示
Out[2]:
A B C
10 20 30 10 20 30 10 20 30 results
0 1 3 0 3 0 0 0 1 0 A20&B10&C20
1 3 2 0 0 5 0 0 0 0 A10&B20
2 0 0 3 0 0 1 0 0 0 A30&B30
3 1 0 0 0 0 0 2 0 0 A10&C10
例如第一行:
对于列 'A',最大值位于列 '20' 下 &
对于列 'B','10' 下只有 1 个值 &
对于 'C' 列,它也只是 '20' 下的一个值 &
所以结果是A20&B10&C20
编辑:在results 列中将“+”替换为“&”,显然我被误解了,你们认为我需要求和,而我需要用分隔符分隔列名
编辑2: 出于某种原因,下面@A.B 提供的解决方案对我不起作用。虽然它正在为他的工作和 google colab 上的示例数据工作。
不知何故.idxmax(skipna = True) 导致ValueError: No axis named 1 for object type Series
我找到了一种解决方法,方法是在此步骤之前转置数据,然后再将其转回。
map_res = lambda x: ",".join(list(filter(None,['' if isinstance(x[a], float) else (x[a][0]+x[a][1]) for a in x.keys()])))
df['results'] = df.replace(0, np.nan)\
.T\ # Transpose here
.groupby(level=0)\ # Remove (axis=1) from here
.idxmax(skipna = True)\
.T\ # Transpose back here
.apply(map_res,axis=1)
我仍然很想知道为什么没有转置它就不能工作?
【问题讨论】:
-
但你不包括零值
-
@Dani Mesejo 是的,零最初是 NaN 值
-
您真的想要用“+”分隔的列名还是总和?
-
@A.B 用“+”或“&”分隔,而不是总和。抱歉,第一天不清楚
-
@Nagib -
am still interested to know why it was is not working without the transpose though?我认为因为取决于熊猫版本,在某些版本中解决方案应该是错误的。
标签: python pandas pivot-table