设置一列的值,等于不为零的列
Set the value of a column, equal to the column that is not zero
作为代码的输出,我正在打印一个数据框,其中包含一些经过处理的信息(即多个销售团队的绩效报告,以下示例仅供说明)
报告显示每个季度的绩效,然后计算每个 KPI 的年度绩效(这是在 4 年内完成的,但为了简单起见,下面的示例仅显示 2020 年)
每个 KPI 的年度绩效假设不同,即有些是每个季度的总和,例如销售额。在其他情况下,它是一个提供信息的 KPI,例如团队中的人数,在这种情况下 我想根据最后一个可用的信息栏设置值。
现在,假设一些团队没有报告他们的团队成员信息。并且此信息仅在他们报告后可用,但是,销售数据可从系统获得并每天更新。
有总和的列没有问题,因为代码最初对列中的所有值求和。但是,我正在努力根据列中可用的最后一个值来设置特定 row/column 的值。即 df.iloc[2, 4] = 6
因为这是 Q3_2020 的值,因为尚未报告第 4 季度。 然而 对于 df.iloc[1, 4] = 4
Q4 的值是可用的,并且它是这样报告的。
df = pd.DataFrame({
'2020_Q1': [2, 3, 6, 20, 20],
'2020_Q2': [2, 3, 6, 20, 20],
'2020_Q3': [5, 3, 6, 20, 20],
'2020_Q4': [5, 4, 6, 20, 20],
'2021_Q1': [5, 3, 7, 20, 20],
'2021_Q2': [5, 4, 7, 20, 20],
'2021_Q3': [5, 4, 0, 20, 20],
}, index = ['People', 'AA', 'BB', 'MM', '$$'])
df
Out[]:
2020_Q1 2020_Q2 2020_Q3 2020_Q4 2021_Q1 2021_Q2 2021_Q3
People 2 2 5 5 5 5 5
AA 3 3 3 4 3 4 4
BB 6 6 6 6 7 7 0
MM 20 20 20 20 20 20 20
$$ 20 20 20 20 20 20 20
生成报告后,输出应如下所示:
###### Solution code here ######
Out[]:
2020_Q1 2020_Q2 2020_Q3 2020_Q4 2020_Total 2021_Q2 2021_Q3 2021_Total
People 2 2 5 5 5 5 5 5
AA 3 3 3 4 4 4 4 5
BB 6 6 6 7 7 7 0 7
MM 20 20 20 20 80 30 30 60
$$ 20 20 20 20 80 30 40 70
到目前为止,我尝试了多种方法,但一直未能找到正确的方法。
尝试使用 if elif 语句
df.loc[['People':'BB'],'2020 Total'] = df.iloc[[0,2],3] if df.iloc[[0,2],3]>0 elif df.iloc[[0,2],2] > 0 df.iloc[[0,2],2] ... else df.iloc[[0,2],1]
Out[]:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
这种方法适用于单行,但不适用于多行。
因为我有多行有这种需求,而且这是一个大forloop的一部分,我想要一个单行代码或者最紧凑的方法来完成这个操作在多个定义的行上。
编辑 我添加了答案中的 DF 代码以澄清和更好地构建问题以供将来参考。
我的解决方案是定义计算年末价值的函数,并使用 pandas.apply
计算 2020_Total
列。
完全可重现的示例:
import pandas as pd
df = pd.DataFrame({
'2020_Q1': [2, 3, 6, 20, 20],
'2020_Q2': [2, 3, 6, 20, 20],
'2020_Q3': [5, 3, 6, 20, 20],
'2020_Q4': [5, 4, 0, 20, 20],
}, index = ['People', 'AA', 'BB', 'MM', '$$'])
def compute_end_year_value(row):
if row.name in ['People', 'AA', 'BB']:
for val in reversed(row):
if val > 0:
return val
return 0
return sum(row)
df['2020_Total'] = df.apply(compute_end_year_value, axis = 1)
我不确定你的数据框的索引是什么样的,所以你可能需要稍微调整一下函数。它是这样工作的:对于有财务数据的行,它计算总和;对于包含其他数据的行,它会查看反向的值并取第一个大于 0 的值。
请注意,如果您多次 运行 该函数,它会计算不同的数字,因为它会将新列 2020_Total
包含在计算中。所以确保你只 运行 它一次或调整代码,这样它就不会成为问题。
作为代码的输出,我正在打印一个数据框,其中包含一些经过处理的信息(即多个销售团队的绩效报告,以下示例仅供说明)
报告显示每个季度的绩效,然后计算每个 KPI 的年度绩效(这是在 4 年内完成的,但为了简单起见,下面的示例仅显示 2020 年)
每个 KPI 的年度绩效假设不同,即有些是每个季度的总和,例如销售额。在其他情况下,它是一个提供信息的 KPI,例如团队中的人数,在这种情况下 我想根据最后一个可用的信息栏设置值。
现在,假设一些团队没有报告他们的团队成员信息。并且此信息仅在他们报告后可用,但是,销售数据可从系统获得并每天更新。
有总和的列没有问题,因为代码最初对列中的所有值求和。但是,我正在努力根据列中可用的最后一个值来设置特定 row/column 的值。即 df.iloc[2, 4] = 6
因为这是 Q3_2020 的值,因为尚未报告第 4 季度。 然而 对于 df.iloc[1, 4] = 4
Q4 的值是可用的,并且它是这样报告的。
df = pd.DataFrame({
'2020_Q1': [2, 3, 6, 20, 20],
'2020_Q2': [2, 3, 6, 20, 20],
'2020_Q3': [5, 3, 6, 20, 20],
'2020_Q4': [5, 4, 6, 20, 20],
'2021_Q1': [5, 3, 7, 20, 20],
'2021_Q2': [5, 4, 7, 20, 20],
'2021_Q3': [5, 4, 0, 20, 20],
}, index = ['People', 'AA', 'BB', 'MM', '$$'])
df
Out[]:
2020_Q1 2020_Q2 2020_Q3 2020_Q4 2021_Q1 2021_Q2 2021_Q3
People 2 2 5 5 5 5 5
AA 3 3 3 4 3 4 4
BB 6 6 6 6 7 7 0
MM 20 20 20 20 20 20 20
$$ 20 20 20 20 20 20 20
生成报告后,输出应如下所示:
###### Solution code here ######
Out[]:
2020_Q1 2020_Q2 2020_Q3 2020_Q4 2020_Total 2021_Q2 2021_Q3 2021_Total
People 2 2 5 5 5 5 5 5
AA 3 3 3 4 4 4 4 5
BB 6 6 6 7 7 7 0 7
MM 20 20 20 20 80 30 30 60
$$ 20 20 20 20 80 30 40 70
到目前为止,我尝试了多种方法,但一直未能找到正确的方法。
尝试使用 if elif 语句
df.loc[['People':'BB'],'2020 Total'] = df.iloc[[0,2],3] if df.iloc[[0,2],3]>0 elif df.iloc[[0,2],2] > 0 df.iloc[[0,2],2] ... else df.iloc[[0,2],1]
Out[]:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
这种方法适用于单行,但不适用于多行。
因为我有多行有这种需求,而且这是一个大forloop的一部分,我想要一个单行代码或者最紧凑的方法来完成这个操作在多个定义的行上。
编辑 我添加了答案中的 DF 代码以澄清和更好地构建问题以供将来参考。
我的解决方案是定义计算年末价值的函数,并使用 pandas.apply
计算 2020_Total
列。
完全可重现的示例:
import pandas as pd
df = pd.DataFrame({
'2020_Q1': [2, 3, 6, 20, 20],
'2020_Q2': [2, 3, 6, 20, 20],
'2020_Q3': [5, 3, 6, 20, 20],
'2020_Q4': [5, 4, 0, 20, 20],
}, index = ['People', 'AA', 'BB', 'MM', '$$'])
def compute_end_year_value(row):
if row.name in ['People', 'AA', 'BB']:
for val in reversed(row):
if val > 0:
return val
return 0
return sum(row)
df['2020_Total'] = df.apply(compute_end_year_value, axis = 1)
我不确定你的数据框的索引是什么样的,所以你可能需要稍微调整一下函数。它是这样工作的:对于有财务数据的行,它计算总和;对于包含其他数据的行,它会查看反向的值并取第一个大于 0 的值。
请注意,如果您多次 运行 该函数,它会计算不同的数字,因为它会将新列 2020_Total
包含在计算中。所以确保你只 运行 它一次或调整代码,这样它就不会成为问题。