我希望得到一些帮助与计算我有点挣扎。我正在处理一些数据(下面复制),我需要创建一个计算,需要第一个值>从另一列中取出0,并基于该值计算一个新的序列,然后将这些数字聚合起来,得到一个累积和。我的原始数据如下所示:
d = {'Final Account': ['A', 'A', 'A' ,'A' , 'A', 'A', 'A','A' ,'A' ,'A', 'A', 'A', 'A'],
'Date': ['Jun-21','Jul-21','Aug-21','Sep-21','Oct-21','Nov-21','Dec-21','Jan-22','Feb-22','Mar-22','Apr-22','May-22','Jun-22'],
'Units':[0, 0, 0, 0, 10, 0, 20, 0, 0, 7, 12, 35, 0]}
df = pd.DataFrame(data=d)
Account Date Units
A Jun-21 0
A Jul-21 0
A Aug-21 0
A Sep-21 0
A Oct-21 10
A Nov-21 0
A Dec-21 20
A Jan-22 0
A Feb-22 0
A Mar-22 7
A Apr-22 12
A May-22 35
A Jun-22 0
对于表,我对我的数据进行初始转换,这是:
df['Conv'] = df['Units'].apply(x/5)
在表中添加一个新列,如下所示:
Account Date Units Conv
A Jun-21 0 0
A Jul-21 0 0
A Aug-21 0 0
A Sep-21 0 0
A Oct-21 10 2
A Nov-21 0 0
A Dec-21 20 4
A Jan-22 0 0
A Feb-22 0 0
A Mar-22 7 1
A Apr-22 12 2
A May-22 35 7
A Jun-22 0 0
在这之后的步骤我开始遇到问题。我需要计算新字段,它取conv字段的第一个值>0,在相同的索引位置,并根据前一行的总和开始新的计算,然后在计算之后将其添加回总和。在python之外,这是通过创建两个列来完成的。一个计算新单位:
(Units - (previous row cumsum of existing units * 2))/5
则现有单位,即已算出的新单位的值的总和。期望的输出应该像这样:
Account Date Units Conv New Units Existing Units (cumsum of new units)
A Jun-21 0 0 0 0
A Jul-21 0 0 0 0
A Aug-21 0 0 0 0
A Sep-21 0 0 0 0
A Oct-21 10 2 2 2
A Nov-21 0 0 0 2
A Dec-21 20 4 3 5
A Jan-22 0 0 0 5
A Feb-22 0 0 0 5
A Mar-22 7 1 0 5
A Apr-22 12 2 0 5
A May-22 35 7 5 10
A Jun-22 0 0 0 10
我正在努力解决的主要问题是从"Conv"中抓取第一个值>0。列,并能够基于可应用于"新单位"的初始值创建新的总和。计算。任何指导都是非常感激的,尽管阅读了很多,我还是碰到了一点砖墙!如果你需要我更好地解释,请问!:)
提前感谢!
我不确定我是否完全理解你想要达到的目的。尽管如此,这里还是尝试重现您的预期结果。对于您的示例框架
groups = (df['Units'].eq(0) & df['Units'].shift().ne(0)).cumsum()
df['New Units'] = 0
last = 0
for _, group in df['Units'].groupby(groups):
i, unit = group.index[-1], group.iloc[-1]
if unit != 0:
new_unit = (unit - last * 2) // 5
last = df.at[i, 'New Units'] = new_unit
确实导致
Final Account Date Units New Units
0 A Jun-21 0 0
1 A Jul-21 0 0
2 A Aug-21 0 0
3 A Sep-21 0 0
4 A Oct-21 10 2
5 A Nov-21 0 0
6 A Dec-21 20 3
7 A Jan-22 0 0
8 A Feb-22 0 0
9 A Mar-22 7 0
10 A Apr-22 12 0
11 A May-22 35 5
12 A Jun-22 0 0
第一步确定Units
列中最后一项与构建新单元相关的块:连续的零,然后是非零,直到第一个零。这个
groups = (df['Units'].eq(0) & df['Units'].shift().ne(0)).cumsum()
在搜索结果
0 1
1 1
2 1
3 1
4 1
5 2
6 2
7 3
8 3
9 3
10 3
11 3
12 4
然后将列Units
沿着这些块分组,如果每个块是非零(零只能发生在最后一个块中),抓住最后一个项目,构建新单元(根据给定的公式)并将其存储在新列New Units
中。
(如果您确实需要Existing Units
列,那么只需在New Units
列上使用.cumsum()
。)
如果有多个帐户(在评论中指出),那么将过程分别应用于每个帐户的一种方法是将其打包到函数中(这里是new_units
),.groupby()
在Final Account
列上,.apply()
将函数打包到组中:
def new_units(sdf):
groups = (sdf['Units'].eq(0) & sdf['Units'].shift().ne(0)).cumsum()
last = 0
for _, group in sdf['Units'].groupby(groups):
i, unit = group.index[-1], group.iloc[-1]
if unit != 0:
new_unit = (unit - last * 2) // 5
last = sdf.at[i, 'New Units'] = new_unit
return sdf
df['New Units'] = 0
df = df.groupby('Final Account').apply(new_units)
尝试使用for循环来执行您提供的示例计算
# initialize new rows to zero
df['new u'] = 0
df['ext u'] = 0
# set first row cumsum
df['ext u'][0] = df['units'][0]//5
# loop through the data frame to perform the calculations
for i in range(1, len(df)):
# calculate new units
df['new u'][i] = (df['units'][i]-2*df['ext u'][i-1])//5
# calculate existing units
df['ext u'][i] = df['ext u'][i-1] + df['new u']
我不确定这些是你正在寻找的确切的表达式,但希望这能让你找到解决方案。值得注意的是,这并没有处理整个"第一值"。0";事情是因为(请随意纠正我,但是)似乎之前你只是在加零,这不会影响任何事情。希望这对你有帮助!