python - Python Pandas Dataframe 中行的条件减法
问题描述
正如解释的那样,我正在尝试解决手头的问题。我有一个数据框,如下所示:
Date Item Type Qty Price
1/1/18 Orange Add 100 25
5/1/18 Orange Add 20 40
8/1/18 Orange Add 40 20
18/1/18 Orange Add 10 35
27/2/18 Orange Sub 100 55
15/4/18 Orange Sub 30 45
我想获得如下中间数据框:
Date Item Type Qty Price Diff
1/1/18 Orange Add 0 25 30
5/1/18 Orange Add 0 40 5
8/1/18 Orange Add 30 20 25
18/1/18 Orange Add 10 35
然后是我想要的最终数据框,如下所示:
Date Item Type Qty Price
8/1/18 Orange Add 30 20
18/1/18 Orange Add 10 35
注意:差异是 Sub 和 Add Price 的差异。并且数量也更新为从添加数量中减去子数量。
你们中的任何人都可以帮助实现它。我正在尝试使用 groupby、应用和转换,但直到现在我还没有得到这个。
我有以下代码,仍在开发中且不完整:
def FruitSummary():
df = pd.DataFrame([
['01/1/18', 'Orange', 'Add', 100, 25],
['05/1/18', 'Orange', 'Add', 20, 40],
['08/1/18', 'Orange', 'Add', 40, 20],
['18/1/18', 'Orange', 'Add', 10, 35],
['27/2/18', 'Orange', 'Sub', 100, 55],
['15/4/18', 'Orange', 'Sub', 30, 45],
['02/1/18', 'Banana', 'Add', 110, 7],
['04/1/18', 'Banana', 'Add', 20, 9],
['11/1/18', 'Banana', 'Add', 40, 4],
['10/2/18', 'Banana', 'Add', 10, 3],
['15/3/18', 'Banana', 'Sub', 100, 9],
['15/4/18', 'Banana', 'Sub', 50, 8],
['10/3/18', 'Kiwi', 'Add', 80, 29],
['12/3/18', 'Berry', 'Add', 25, 5],
['18/4/18', 'Berry', 'Add', 15, 8]],
columns=['Date', 'Item', 'Type', 'Qty', 'Price'])
print(df)
def fruit_stat(dfIN):
print(dfIN)
print((dfIN['Type'] == 'Sub').unique(), (dfIN['Type'] == 'ODD').unique())
if len(dfIN) > 1 and (True in (dfIN['Type'] == 'Sub').unique()):
print(dfIN['Item'].iloc[1], "'len > 1'", "'Sub True'")
dfFS = df.groupby(['Item']).apply(fruit_stat)
print(dfFS)
解决方案
我能够找到一些解决方案,不确定它是否是最佳的,或者可能有更好的解决方案。
df = pd.DataFrame([['01/1/18', 'Orange', 'Add', 100, 25],
['05/1/18', 'Orange', 'Add', 20, 40],
['08/1/18', 'Orange', 'Add', 40, 20],
['18/1/18', 'Orange', 'Add', 10, 35],
['27/2/18', 'Orange', 'Sub', 100, 55],
['15/4/18', 'Orange', 'Sub', 30, 45],
['02/1/18', 'Banana', 'Add', 110, 7],
['04/1/18', 'Banana', 'Add', 20, 9],
['11/1/18', 'Banana', 'Add', 40, 4],
['10/2/18', 'Banana', 'Add', 10, 3],
['15/3/18', 'Banana', 'Sub', 100, 9],
['15/4/18', 'Banana', 'Sub', 50, 8],
['10/3/18', 'Kiwi', 'Add', 80, 29],
['12/3/18', 'Berry', 'Add', 25, 5],
['18/4/18', 'Berry', 'Add', 15, 8],
['16/3/18', 'Cherry', 'Add', 25, 5],
['21/4/18', 'Cherry', 'Sub', 25, 8],
['19/3/18', 'Grapes', 'Add', 25, 5],
['23/4/18', 'Grapes', 'Sub', 15, 8]],
columns=['Date', 'Item', 'Type', 'Qty', 'Price'])
def FruitSummary(df):
df['CumSum'] = df.groupby(['Item', 'Type'])['Qty'].cumsum()
print(df)
def fruit_stat(dfg):
if dfg[dfg['Type'] == 'Sub']['Qty'].count():
subT = dfg[dfg['Type'] == 'Sub']['CumSum'].iloc[-1]
dfg['Qty'] = np.where((dfg['CumSum'] - subT) <= 0, 0, dfg['Qty'])
dfg = dfg[dfg['Qty'] > 0]
if(len(dfg) > 0):
dfg['Qty'].iloc[0] = dfg['CumSum'].iloc[0] - subT
return dfg
dfFS = df.groupby(['Item'], as_index=False).apply(fruit_stat).drop(['CumSum'], axis=1).reset_index(drop=True)
print(dfFS)
上面的代码会产生如下的答案:
Date Item Type Qty Price
0 11/1/18 Banana Add 20 4
1 10/2/18 Banana Add 10 3
2 12/3/18 Berry Add 25 5
3 18/4/18 Berry Add 15 8
4 19/3/18 Grapes Add 10 5
5 10/3/18 Kiwi Add 80 29
6 08/1/18 Orange Add 30 20
7 18/1/18 Orange Add 10 35
推荐阅读
- java - 无法获取 POM.xml 插件配置中提供的密码
- python - 如何使用Python将姓氏返回到前面,然后跟随名字的首字母?
- bixby - Bixby Capsule - 与现有应用程序交互?
- powershell - nuget 中 .config 文件的令牌替换(powershell 或 AzureDevOps 任务)
- compiler-construction - 使用 flex 和 bison 的编译器的 IF-ELSE 语句
- ios - 如何快速从 HealthKit 中获取氧饱和度?
- ruby-on-rails - 在 Relation 中添加新对象并一起渲染 JSON
- java - KafkaConsumer 和 ScheduledExecutorService 不起作用
- javascript - 平滑滚动条 - 什么执行滚动事件?
- android - 几个小时后,我的无尽后台服务自动停止。为什么?