我有以下带有多级列的dataframe
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'下只有一个值;
对于列'C',它也是'20'下的一个值;
因此结果将是A20&B10&C20
编辑:在results
列中将“+”替换为“&;”,显然我被误解了,你们认为我需要求和,而我需要用分隔符分隔列名
Edit2: 由于某种原因,下面@A.B提供的解决方案对我不起作用。虽然它是在他的工作和谷歌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)
我仍然有兴趣知道为什么没有转置它就不能工作
尝试:
印刷品:
想法是用} ,所有带有} 获取索引,通过
NaN
替换0
,所以如果使用^{NaN
的行都将被删除。然后通过^{map
映射第二和第三个元组值,并将join
聚合到每个索引的新列-第一级:按级别0和轴=1分组
您可以使用idxmax以元组的形式获取最大子级别索引(同时跳过NAN)
将函数应用于concat名称的行(axix-1)
在(应用于行的)函数中,迭代键/列并连接列级别。将Nan(类型为“float”)替换为空字符串,并在以后对其进行筛选
如果最初有nan并让它们保留,则不需要df.replace(0,np.nan)
这是输出
相关问题 更多 >
编程相关推荐