【问题标题】:Get column name based on condition in pandas根据熊猫中的条件获取列名
【发布时间】:2020-06-13 18:23:27
【问题描述】:

我有一个如下的数据框:

如果特定行的列在该列中包含 1,我想获取该列的名称。

例如

For Row 1: Blanks,
For Row 2: Manufacturing,
For Row 3: Manufacturing,
For Row 4: Manufacturing,
For Row 5: Social, Finance, Analytics, Advertising,

现在我只能获得完整的行:

primary_sectors = lambda primary_sector: sectors[
    sectors["category_list"] == primary_sector
]

请帮我获取上述数据框中列的名称。

我试过这段代码:

primary_sectors("3D").filter(items=["0"])

它给我输出为1,但我需要输出为Manufacturing

【问题讨论】:

标签: python python-3.x pandas machine-learning


【解决方案1】:

首先

您的问题非常含糊,我建议在@sammywemmy 的评论中阅读link。如果我正确理解您的问题...我们将首先讨论这个面具:

df.columns[      
    (df == 1)        # mask 
    .any(axis=0)     # mask
]

发生了什么事?让我们从df.columns[**HERE**] 开始向外工作:

  1. (df == 1) 使用 True/False(1/0) 对 df 进行布尔掩码
  2. .any() 根据docs

“返回 False,除非在系列中或沿 Dataframe 轴至少有一个元素为 True 或等效”。

这给了我们一个方便的Series 来屏蔽列名。

我们将使用此示例为您的以下解决方案自动化


下一步:

自动获取(<row index> ,[<col name>, <col name>,..]) 的输出,其中行值中有1。虽然这在大型数据集上会慢一些,但它应该可以解决问题:

import pandas as pd

data = {'foo':[0,0,0,0], 'bar':[0, 1, 0, 0], 'baz':[0,0,0,0], 'spam':[0,1,0,1]}
df = pd.DataFrame(data, index=['a','b','c','d'])

print(df)

   foo  bar  baz  spam
a    0    0    0     0
b    0    1    0     1
c    0    0    0     0
d    0    0    0     1
# group our df by index and creates a dict with lists of df's as values
df_dict = dict(
    list(
        df.groupby(df.index)
    )
)

下一步是 for 循环,它迭代 df_dict 中每个 df 的内容,使用我们之前创建的掩码检查它们,并打印预期的结果:

for k, v in df_dict.items():               # k: name of index, v: is a df
    check = v.columns[(v == 1).any()]
    if len(check) > 0:
        print((k, check.to_list()))
('b', ['bar', 'spam'])
('d', ['spam'])

旁注:

您看到我如何生成可以轻松复制的示例数据了吗?今后,请尝试使用可复制的已发布示例数据提出问题。这样可以帮助您更好地了解您的问题,我们也更容易为您解答。

【讨论】:

  • 我刚刚更新了它以获得正确的输出。不客气。如果我解决了问题标记为已回答并投票,请:)
【解决方案2】:

使用DataFrame.dot:

df1 = df.dot(df.columns)

如果每行有多个1

df2 = df.dot(df.columns + ';').str.rstrip(';')

【讨论】:

    【解决方案3】:

    获取列名分为两部分。

    如果你想要一个新的列名,那么条件应该是唯一的,因为它只会为每一行提供 1 个列名。

    data = {'foo':[0,0,3,0], 'bar':[0, 5, 0, 0], 'baz':[0,0,2,0], 'spam':[0,1,0,1]}
    df = pd.DataFrame(data)
    df=df.replace(0,np.nan)
    df
        foo bar baz spam
    0   NaN NaN NaN NaN
    1   NaN 5.0 NaN 1.0
    2   3.0 NaN 2.0 NaN
    3   NaN NaN NaN 1.0
    

    如果您正在寻找最小值或最大值

    max= df.idxmax(1)
    min = df.idxmin(1)
    out=  df.assign(max=max , min=min)
    out
    
        foo bar baz spam   max    min
    0   NaN NaN NaN NaN    NaN    NaN
    1   NaN 5.0 NaN 1.0    bar    spam
    2   3.0 NaN 2.0 NaN    foo    baz
    3   NaN NaN NaN 1.0    spam   spam
    

    第二种情况,如果您的条件在多个列中得到满足,例如您正在寻找包含 1 的列并且您正在寻找列表,因为它无法在同一数据帧中进行调整。

    str_con= df.astype(str).apply(lambda x:x.str.contains('1.0',case=False, na=False)).any()
    df.column[str_con]
    #output
    Index(['spam'], dtype='object') #only spam contains 1
    
    

    或者您正在寻找数值条件列包含大于 1 的值

    num_con = df.apply(lambda x:x>1.0).any()
    df.columns[num_con]
    #output
    Index(['foo', 'bar', 'baz'], dtype='object') #these col has higher value than 1
    

    快乐学习

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 1970-01-01
      • 2019-09-15
      • 2021-10-01
      • 2022-11-10
      • 2018-09-25
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多