Python 如何在熊猫中跨列计数

Python 如何在熊猫中跨列计数,python,pandas,boolean,Python,Pandas,Boolean,我想求各列中每个值的总数。这相当于Excel中的COUNTIFs。但是,我希望在列中填充值,而不是在单独的groupby语句中填充值 所以,如果第1行有5列,它们的值如下:1,1,3,1,5 然后,评级_1=3、评级_2=0、评级_3=1、评级_4=0和评级_5=1 或(3,0,1,0,1) 我正在使用下面的代码,但无法获得要在循环中添加的布尔值(我所有的研究都表明它们应该加起来很好!) 现在,我得到以下(二进制)输出:1,0,1,0,1(应该是3,0,1,0,1) 我也很乐意让这段代码更干净、

我想求各列中每个值的总数。这相当于Excel中的COUNTIFs。但是,我希望在列中填充值,而不是在单独的groupby语句中填充值

所以,如果第1行有5列,它们的值如下:1,1,3,1,5

然后,评级_1=3、评级_2=0、评级_3=1、评级_4=0和评级_5=1 或(3,0,1,0,1)

我正在使用下面的代码,但无法获得要在循环中添加的布尔值(我所有的研究都表明它们应该加起来很好!)

现在,我得到以下(二进制)输出:1,0,1,0,1(应该是3,0,1,0,1)


我也很乐意让这段代码更干净、更高效,但最关心的是让它工作起来!提前谢谢你的帮助

您可以使用
groupby
创建一个临时数据帧,您可以对其进行处理并最终与
df
合并

np.random.seed(1) # always add a sample with random state for reproducibility
df = pd.DataFrame(np.random.randint(0,5,size=(5, 5)), columns=list('ABCDE'))


df2 = df.stack().droplevel(-1).reset_index()
df2 = (
    df2.groupby(df2.columns.to_list())
    .size().unstack()
    .fillna(0).astype(int)
)
df = pd.concat([df, df2], axis=1)    
输出

   A  B  C  D  E  0  1  2  3  4
0  3  4  0  1  3  1  1  0  2  1
1  0  0  1  4  4  2  1  0  0  2
2  1  2  4  2  4  0  1  2  0  2
3  3  4  2  4  2  0  0  2  1  2
4  4  1  1  0  1  1  3  0  0  1

我理解,这与在Excel中如何添加公式非常相似,但是考虑将数据和结果保持为单独的数据框(即跳过<代码> Pd.CONTAG/COD>),以便在进一步的代码中获得更好的可用性。如果您需要对原始数据执行其他操作,则必须删除列,这不是常见的做法,任何使用您的代码的人都可能不希望出现这种行为。

稍微澄清一下问题

df
    
   A  B  C  D  E  
0  4  3  4  2  0         
1  0  4  2  3  3          
2  3  4  1  2  1          
3  0  2  3  0  2          
4  2  4  1  3  2  

    
跨行的所需结果: 以第0行为例

  • 统计行中0的出现次数。有1个。将其放入“排名0”列中
  • 计算行中1的出现次数。有0个。将其放在“排名_1”列中
  • 等等

    所需输出:

       A  B  C  D  E  Ranking_0  Ranking_1  Ranking_2  Ranking_3  Ranking_4
    0  4  3  4  2  0          1          0          1          1          2
    1  0  4  2  3  3          1          0          1          2          1
    2  3  4  1  2  1          0          2          1          1          1
    3  0  2  3  0  2          2          0          2          1          0
    4  2  4  1  3  2          0          1          2          1          1
    
    有很多方法可以做到这一点,所以我将使用一种对我来说比较简单的方法

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randint(0,5,size=(5, 5)), columns=list('ABCDE'))
    
    # The numbers you want to check for
    nums = [0,1,2,3,4]
    for num in nums: 
         df['Ranking_'+str(num)] = (df.iloc[:,0:5]).isin({num}).sum(1)
    
  • 小心在前5列中求和,否则您将开始在排名列中添加!这就是为什么我做了
    df.iloc[:,0:5)
  • 我使用了
    .isin({})
    仅仅因为它是干净的。还有其他方法
  • .sum(1)
    沿水平行(轴=1)求和

  • 您不需要任何循环,但是您现有的数据结构和所需的输出并不清晰。您可以添加一个实际可读的示例数据集以及您期望的输出是什么。
    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randint(0,5,size=(5, 5)), columns=list('ABCDE'))
    
    # The numbers you want to check for
    nums = [0,1,2,3,4]
    for num in nums: 
         df['Ranking_'+str(num)] = (df.iloc[:,0:5]).isin({num}).sum(1)