繁体   English   中英

Pandas - 如何向数据框添加多个条件列?

[英]Pandas - how to add multiple conditional columns to dataframe?

所以我想做的是根据条件创建几个计算并将它们添加到数据帧中。 下面是一些代码作为示例:

data = pd.DataFrame({'Project':  ['Project 1', 'Project 2', ' Project 3', 'Project 4', 'Project 5', 'Project 6', 'Project 7', 'Project 8', 'Project 9', 'Project 10'],
        'Date': ['10/1/2020', '10/1/2020', '11/1/2020', '12/1/2020', '12/1/2020', '12/1/2020', '2/1/2021', '2/1/2021', '3/1/2021', '4/1/2021'],
       'Team': ['Team 1', 'Team 2', 'Team 3', 'Team 2', 'Team 2', 'Team 2', 'Team 1', 'Team 1', 'Team 1', 'Team 1'],
       'Timely': ['Yes', 'No', 'No', 'Yes', 'Yes', 'No', 'No', 'Yes', 'Yes', 'Yes']})
                                       
df1=data.groupby('Team')['Timely'].apply(lambda x: (x=='Yes').sum()).reset_index(name='Yes Count')       

df1

运行此代码将为我提供一个表格,其中显示每个团队及时 = Yes 的项目数。 假设我想在表格中添加第二列以显示总计数,其中及时 = 否,第三列和第四列显示每个团队的百分比是和否。 我该怎么做?

在我看来,你只想要一个交叉表。 使用pd.crosstab计算比使用groupby/apply方法更直接。 虽然pd.crosstab不是最有效的方法,但它工作得很好。

第一个片段为我们提供了每个团队的“是”和“否”计数。 我们还得到一个“总计”列,它是“是”+“否”的总和:

xtab = pd.crosstab(data["Team"], data["Timely"], margins=True, margins_name="Total")

print(xtab)
Timely  No  Yes  Total
Team                  
Team 1   1    4      5
Team 2   2    2      4
Team 3   1    0      1
Total    4    6     10

现在让我们通过将它们除以我们的“总计”列来计算“否”和“是”的百分比细分:

norm_xtab = xtab[["No", "Yes"]].div(xtab["Total"], axis=0)

print(norm_xtab)
Timely   No  Yes
Team            
Team 1  0.2  0.8
Team 2  0.5  0.5
Team 3  1.0  0.0
Total   0.4  0.6

然后我们可以将这两个数据帧与pd.concat函数水平组合。 我们还可以为每个“子数据帧”命名,例如数据帧的一个块将仅用于计数数据,另一块将用于标准化/基于百分比的数据:

out = pd.concat([xtab, norm_xtab], keys=["count", "percent"], axis=1)
out = out.rename(columns={"No": "untimely", "Yes": "timely"}, level=1)


print(out)
          count               percent       
Timely untimely timely Total untimely timely
Team                                        
Team 1        1      4     5      0.2    0.8
Team 2        2      2     4      0.5    0.5
Team 3        1      0     1      1.0    0.0
Total         4      6    10      0.4    0.6

连接的结果是一个以多索引作为列的 DataFrame。 如果您不熟悉 pd.MultiIndex,您可以使用此代码段将您的结果展平为您可能更熟悉的内容:

out.columns = ["{}_{}".format(*colname) for colname in out.columns]

print(out)

        count_untimely  count_timely  count_Total  percent_untimely  percent_timely
Team                                                                               
Team 1               1             4            5               0.2             0.8
Team 2               2             2            4               0.5             0.5
Team 3               1             0            1               1.0             0.0
Total                4             6           10               0.4             0.6

要更改下面评论中的列名称,您只需再运行一次rename

out = out.rename(columns=lambda colname: colname.replace("count_", ""))

print(out)
        untimely  timely  Total  percent_untimely  percent_timely
Team                                                             
Team 1         1       4      5               0.2             0.8
Team 2         2       2      4               0.5             0.5
Team 3         1       0      1               1.0             0.0
Total          4       6     10               0.4             0.6

要将小数转换为整数百分比,您需要乘以 100,然后四舍五入到 0 位小数或使用字符串格式来修剪尾随小数(我将向您展示如何执行这两个操作),并添加另一个字符串格式让“%”出现。

percentages = (out
               .filter(like="percent")      # select columns that contain the string "percent"
               .mul(100)                    # Multiply everything by 100
               .round(0)                    # If you don't want to perform any rounding, get rid of this line
               .applymap("{:.0f}%".format)) # Apply string formatting to trim the decimal.

print(percentages)
       percent_untimely percent_timely
Team                                  
Team 1              20%            80%
Team 2              50%            50%
Team 3             100%             0%
Total               40%            60%

如果您希望这些值反映在我们的out数据框中:

out.loc[:, percentages.columns] = percentages

print(out)
        untimely  timely  Total percent_untimely percent_timely
Team                                                           
Team 1         1       4      5              20%            80%
Team 2         2       2      4              50%            50%
Team 3         1       0      1             100%             0%
Total          4       6     10              40%            60%

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM