提问人:spectre 提问时间:4/16/2023 最后编辑:spectre 更新时间:4/16/2023 访问量:61
如果 2 个 pandas 数据帧在 python 中具有相同的条目,请执行一些操作
Perform some operation if 2 pandas dataframe have same entries in python
问:
我有 2 个数据帧(购买和销售),如下所示:
购买:
名字 | 项目 | 凭证 | Amt | 数量 |
---|---|---|---|---|
一个 | 项目1 | 购买 | 10000 | 100 |
B | 项目2 | 购买 | 500 | 50 |
B | 项目1 | 购买 | 2000 | 20 |
C | 项目3 | 购买 | 1000 | 100 |
D | 项目4 | 购买 | 500 | 100 |
一个 | 项目3 | 购买 | 5000 | 50 |
销售:
名字 | 项目 | 凭证 | Amt | 数量 |
---|---|---|---|---|
一个 | 项目1 | 销售 | 5300 | 50 |
B | 项目2 | 销售 | 450 | 40 |
B | 项目1 | 销售 | 1675 | 15 |
C | 项目3 | 销售 | 1800 | 100 |
我想要一个输出数据帧,如果该人 () 出售了一件商品,则应从购买数据帧中扣除 and,并且应使用剩余的 and 创建一个新的数据帧,如下所示:Name
Amt
Qty
Amt
Qty
输出数据帧:
名字 | 项目 | 凭证 | Amt | 数量 |
---|---|---|---|---|
一个 | 项目1 | 剩余 | 4700 | 50 |
一个 | 项目3 | 剩余 | 5000 | 50 |
B | 项目2 | 剩余 | 50 | 10 |
B | 项目1 | 剩余 | 325 | 5 |
C | 项目3 | 剩余 | -800 | 0 |
D | 项目4 | 剩余 | 500 | 100 |
请注意,已从购买数据帧中扣除人员 () 已售出的任何项目,其余项目 ( 和 ) 存储在新的输出数据帧中。此外,即使如此,人们也从未出售过任何物品,因此它应该包含在输出数据帧中。Name
Amt
Qty
D
提前致谢!
数据帧
import pandas as pd
Purchases = {
"Name": ["A", "B", "B", "C", "D", "A"],
"item": ["Item1", "Item2", "Item1", "Item3", "Item4", "Item3"],
"voucher": ["Purchase", "Purchase", "Purchase", "Purchase", "Purchase", "Purchase"],
"Amt": [10000, 500, 2000, 1000, 500, 5000],
"Qty": [100, 50, 20, 100, 100, 50],
}
Purchases = pd.DataFrame(Purchases)
Sales = {
"Name": ["A", "B", "B", "C"],
"item": ["Item1", "Item2", "Item1", "Item3"],
"voucher": ["Sales", "Sales", "Sales", "Sales"],
"Amt": [5300, 450, 1675, 1800],
"Qty": [50, 40, 15, 100],
}
Sales = pd.DataFrame(Sales)
答:
2赞
Laurent B.
4/16/2023
#1
Purchases = Purchases.set_index(['Name', 'item'])
Sales = Sales.set_index(['Name', 'item'])
Purchases['Amt'].update(Purchases['Amt'].sub(Sales['Amt']))
Purchases['Qty'].update(Purchases['Qty'].sub(Sales['Qty']))
Purchases = Purchases.reset_index().sort_values(by=['Name'])
print(Purchases)
Name item voucher Amt Qty
0 A Item1 Purchase 4700 50
5 A Item3 Purchase 5000 50
1 B Item2 Purchase 50 10
2 B Item1 Purchase 325 5
3 C Item3 Purchase -800 0
4 D Item4 Purchase 500 100
评论
0赞
Laurent B.
4/16/2023
感谢您提供此信息 Corralien,将在下一个 Pandas 版本(即 Pandas 2)中被弃用。所以现在必须养成良好的习惯;-)ìnplace
0赞
Corralien
4/16/2023
可能也会被弃用。(我希望:-))。我认为所有方法都应该始终返回一个副本(显式比隐式更好)。只有 、 和其他项赋值应就地修改 DataFrame/Series,因为它们是显式的。恕我直言:-)update
.loc
.iloc
0赞
Laurent B.
4/16/2023
是的,当然它会更可取,但在 Pandas 2 : pandas.pydata.org/docs/reference/api/pandas.Series.update.html (版本 2.0.0(稳定版))中未被弃用。但我必须承认,即使非常有用,我也不喜欢返回 None 的方法(buggs 的来源)。update
update
2赞
Corralien
4/16/2023
#2
您可以使用:merge
# dfP = PURCHASE dataframe
# dfS = SALES dataframe
out = (Purchases.merge(Sales.drop(columns='voucher'), on=['Name', 'item'],
suffixes=(None, '_'), how='left')
.assign(Amt=lambda x: x['Amt'] - x.pop('Amt_').fillna(0).astype(int),
Qty=lambda x: x['Qty'] - x.pop('Qty_').fillna(0).astype(int),
voucher='Remaining'))
输出:
>>> out
Name item voucher Amt Qty
0 A Item1 Remaining 4700 50
1 B Item2 Remaining 50 10
2 B Item1 Remaining 325 5
3 C Item3 Remaining -800 0
4 D Item4 Remaining 500 100
5 A Item3 Remaining 5000 50
2赞
mozway
4/16/2023
#3
使用良好的旧索引对齐方式:
tmp = Purchases.set_index(['Name', 'item'])
out = (tmp
.sub(Sales.set_index(['Name', 'item'])[['Amt', 'Qty']])
.combine_first(tmp).assign(voucher='Remaining')
.reset_index()[Purchases.columns]
)
输出:
Name item voucher Amt Qty
0 A Item1 Remaining 4700.0 50.0
1 A Item3 Remaining 5000.0 50.0
2 B Item1 Remaining 325.0 5.0
3 B Item2 Remaining 50.0 10.0
4 C Item3 Remaining -800.0 0.0
5 D Item4 Remaining 500.0 100.0
评论
0赞
Laurent B.
4/16/2023
我不知道我是爱你还是讨厌你哈哈;-p
0赞
mozway
4/16/2023
@LaurentB。那就宁愿爱我吧,这个世界上的仇恨已经够多了:p
0赞
Laurent B.
4/16/2023
好吧,这就是我的骰子指示我的:-p
下一个:如何根据R中的条件选择某个时期?
评论