Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用滚动总计构建Python函数?_Python_Pandas_Function_Lambda - Fatal编程技术网

如何使用滚动总计构建Python函数?

如何使用滚动总计构建Python函数?,python,pandas,function,lambda,Python,Pandas,Function,Lambda,我希望构建一个函数,为下面的数据帧按代码逐日创建滚动总计,其中日期上每个代码的输入从日期上每个代码的输出中减去,此小计是从前几天的总计中减去的,但总计必须大于等于0(我在下面的所需输出中包含了一个示例) 下面是我的输入和使用的函数的示例,以及我所需输出的示例 df1-In s = """ Date Code Quantity 0 10/01/2019 A 20 3 11/01/2019 A 2 7 12/01/201

我希望构建一个函数,为下面的数据帧按代码逐日创建滚动总计,其中日期上每个代码的输入从日期上每个代码的输出中减去,此小计是从前几天的总计中减去的,但总计必须大于等于0(我在下面的所需输出中包含了一个示例)

下面是我的输入和使用的函数的示例,以及我所需输出的示例

df1-In

s = """        Date    Code    Quantity
0   10/01/2019  A   20
3   11/01/2019  A   2
7   12/01/2019  A   4
11  13/01/2019  A   10
"""
df2-输出

s ='''    Date     Code   Quantity
0   11/01/2019  A   5
3   12/01/2019  A   100
4   15/01/2019  A   1
6   16/01/2019  A   2
'''
s = """        Date    Code    Quantity
0   10/01/2019  A   20
3   11/01/2019  A   17
7   12/01/2019  A   0
11  13/01/2019  A   10
12  14/01/2019  A   10
15  15/01/2019  A   9
16  16/01/2019  A   7
"""
代码

df3 = df1.merge(df2, how='outer', left_on=['date', 'code'], right_on=['date', 'code']).fillna(0)
df3['qty1'] = df3['qty_x'] - df3['qty_y']
df3['qty'] = 0
def final_adder(x):
    x.qty_x = x.qty_x
    print(x)
    return x
df_final = df3.groupby(['code']).apply(final_adder)
df_final['qty'] = df_final['qty'].clip(lower=0)
df_final.drop(['qty_x', 'qty_y','qty1'], inplace=True, axis=1)


          date code  qty_x  qty_y qty1  qty
0   10/01/2019   A   20.0    0.0  20.0    0
3   11/01/2019   A    2.0    5.0  -3.0    0
7   12/01/2019   A    4.0  100.0 -96.0    0
11  13/01/2019   A   10.0    0.0  10.0    0
所需输出

s ='''    Date     Code   Quantity
0   11/01/2019  A   5
3   12/01/2019  A   100
4   15/01/2019  A   1
6   16/01/2019  A   2
'''
s = """        Date    Code    Quantity
0   10/01/2019  A   20
3   11/01/2019  A   17
7   12/01/2019  A   0
11  13/01/2019  A   10
12  14/01/2019  A   10
15  15/01/2019  A   9
16  16/01/2019  A   7
"""

关于SO,有一整套问题涉及具有限制的累积运算(例如:“当累积和变为负值时重置为零”)。这与具有已知重置点的累积运算不同(例如,来自另一列,或存在NaN等),因为条件涉及累积值本身

在当前的熊猫或numpy中,没有干净的方法以矢量化的方式实现这一点

我所知道的最好(最快)的方法是使用
numba
。根据您的问题稍加修改和调整:

来自numba import njit
@njit
def poscumsum(x):
总数=0
结果=np.空(x.形)
对于枚举(x)中的i,y:
总计+=y
如果总数<0:
总数=0
结果[i]=总数
返回结果
使用此功能,您可以执行以下操作:

a=df1.设置索引(['code','Date'])
b=df2.set_索引(['Code','Date'])
idx=a.index.union(b.index.sort_值()
df3=(a.reindex(idx,fill_值=0)-b.reindex(idx,fill_值=0))
#可选:在每个组内将日期重采样为每日:
df3=df3.groupby('Code')。重采样('D',level='Date')。sum()
df3['Quantity']=df3.groupby('Code')['Quantity'].transform(
lambda g:poscumsum(g.values))
关于问题中提供的数据:

>>df3
量
代码日期
A 2019-01-10 20
2019-01-11        17
2019-01-12         0
2019-01-13        10
2019-01-14        10
2019-01-15         9
2019-01-16         7
如果愿意,也可以使用“合并”。下面是一个示例,其中保存了所有中间结果(用于法医分析):

df3=df1.merge(df2,on=['code','Date'],how='outer',sort=True)。fillna(0)
#可选:在每个组内将日期重采样为每日:
df3=df3.set_index(['Code','Date']).groupby('Code').resample('D',level='Date').sum()
df3['diff']=df3['Quantity\u x']-df3['Quantity\u y']
df3['cumdiff']=df3.groupby('Code')['diff'].transform(
lambda g:poscumsum(g.values))
df3
#输出:
数量×数量×差异
代码日期
A 2019-01-10 20.0 0.0 20.0 20.0
2019-01-11         2.0         5.0  -3.0     17.0
2019-01-12         4.0       100.0 -96.0      0.0
2019-01-13        10.0         0.0  10.0     10.0
2019-01-14         0.0         0.0   0.0     10.0
2019-01-15         0.0         1.0  -1.0      9.0
2019-01-16         0.0         2.0  -2.0      7.0

最简单的是合并后的for循环。感谢您的帮助,当我有一个“代码”时,它可以完美地工作。但是,如果我引入第二个“代码”,“B”,我会遇到以下错误:ValueError:无法处理非唯一的多索引!不确定“如果我引入第二个代码”是什么意思.我测试了多个代码混合在一起,效果很好(不包括
code,date
但不在
df1
中)。您可能希望用额外的示例更新您的问题(当前建议的答案不适合您的需要的示例)。我现在已经修复了错误,我刚刚编辑了df2的输入数据和所需的输出。如果代码有“数量”,我希望它在未来的每一天出现,即使它没有出现在每天的输入或输出数据帧中。我想更新的问题现在显示了这一点。我希望这是有意义的。我明白了:您想要整个外部连接。没问题。更新的答案。当然,请参阅更新答案中的“可选重采样”:只需在进行累积和之前,为每个代码组插入日期的每日重采样:df3=df3.groupby('Code')。重采样('D',level='Date')。sum()