首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Python:按行中的非零值获取列名

Python:按行中的非零值获取列名
EN

Stack Overflow用户
提问于 2020-08-08 07:26:39
回答 4查看 2.5K关注 0票数 2

假设我有10行3列。每行只有一个非零值,每个列的位置在任何行之间都不同。

我如何迭代每一行,检查是否存在任何非零值,检查其列索引,并获得(存储在内存中)适当的列名?

我尝试了几种使用熊猫图书馆的方法,但没有找到任何捷径。

原始数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
index  A  B    C  D                 
11     0  3    0  0     
136    0  0    0  1     
186    0  0  184  0     
258    0  0   15  0     
455    0  1    0  0     
628    0  0    1  0    
774    0  0    2  0     
829    0  0    1  0     
1004   0  0  113  0     
1008   0  0    1  0     

三个不同索引(136、455、1008)的预期输出之一示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
['D', 'B', 'C']

当然,输出可以是类似于列表的任何其他内容。但是这个具体的例子对我来说已经足够了。

认定:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
empty_list = []    
memory_var = [empty_list.append(row.sort_values().max()) for row in 
             df.itterows()]
print(memory_var)

这有助于我创建一个仅包含每一行中最高值的列表。现在,我需要得到这些值的列名。使用"idxmax()“方法返回一个错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
'numpy.float64' object has no attribute 'idxmax'

更新:

为我的案子找到了正确的解决方案。具体列的提取可通过以下方式进行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
row[:].sort_values().idxmax()
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-08-08 11:22:55

idxmax是这方面的完美选择。原始数据包括D列,所以我也使用了它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from io import StringIO
import pandas as pd

data = '''index  A  B    C  D                 
11     0  3    0  0     
136    0  0    0  1     
186    0  0  184  0     
258    0  0   15  0     
455    0  1    0  0     
628    0  0    1  0    
774    0  0    2  0     
829    0  0    1  0     
1004   0  0  113  0     
1008   0  0    1  0   
'''
df = (pd.read_csv(StringIO(data), sep='\s\s+', engine='python')
        .set_index('index'))
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# apply idxmax and show result
df['col'] = df.apply(lambda x: x.idxmax(), axis=1)
print(df)

       A  B    C  D col
index                  
11     0  3    0  0   B
136    0  0    0  1   D
186    0  0  184  0   C
258    0  0   15  0   C
455    0  1    0  0   B
628    0  0    1  0   C
774    0  0    2  0   C
829    0  0    1  0   C
1004   0  0  113  0   C
1008   0  0    1  0   C
票数 3
EN

Stack Overflow用户

发布于 2020-08-08 07:47:39

这就是你要找的吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a_df = pd.DataFrame({"a":[1,0,0,0], "b":[0,3,0,0], "c":[0,0,0,7], "d":[0,0,0,0]})
>>> a_df
   a  b  c  d
0  1  0  0  0
1  0  3  0  0
2  0  0  0  0
3  0  0  7  0

>>> a_df = a_df.replace(0, np.nan)
>>> a_df
     a    b    c   d
0  1.0  NaN  NaN NaN
1  NaN  3.0  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  NaN  7.0 NaN

>>> a_df.dropna(how="all", axis=1).columns.tolist()
['a', 'b', 'c']

如果要保存原始df,请执行以下操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a_df.replace(0, np.nan).dropna(how="all", axis=1).columns.tolist()
['a', 'b', 'c']

>>> a_df
   a  b  c  d
0  1  0  0  0
1  0  3  0  0
2  0  0  0  0
3  0  0  7  0
票数 1
EN

Stack Overflow用户

发布于 2020-08-08 08:44:53

一种替代方法,在原始DataFrame的末尾添加一个列,其中包含非零列名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
df = pd.DataFrame({'x' : [ 0,0,9],'y' : [-1,0,0],'z' : [0,1.1,0]},index=['a','b','c'])
df["non_zero_columns"] = df.where(df == 0, 
                                  other=df.apply(lambda x: x.name), 
                                  axis=1).where(df != 0, 
                                                other="").apply(lambda row: ''.join(row.values), axis=1)

‘'df’现在是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    x   y   z   non_zero_columns
a   0   -1  0.0 y
b   0   0   1.1 z
c   9   0   0.0 x

将一行分隔开,其中两个调用set zeros将空字符串和非零值设置为它们所在的列的名称。这些值(空字符串和列名)是在apply()中连接起来创建"non_zero_columns“列的字符串。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63317109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文