我有一個充滿發票列的資料集,包括:
- 案例ID
- 顧客
- 供應商
- 零件號
- 成本。
該資料集包括費用和積分。我想洗掉他們從 DataFrame 中記入的 Credits 和 Charges。我想洗掉原件中作為積分及其相關費用的行。但在某些情況下,交易因意外而被收取兩次費用,因此資訊是重復的。如果有積分,我不想洗掉重復項,因為重復項也需要積分。
我有原來的df。我創建了一個 Charge df,其中所有行的 Cost > 0 從原始開始。我創建了一個信用 df,它是原始成本 < 0 的所有行。
我的問題是我是否使用df1[~df1.isin(df2)].dropna()或 在這種情況下:
invoiced[~invoiced.isin(credits)].dropna()
如何指定我只希望洗掉該行一次?是否可以?
ex:
invoice =
Case| Part_Number | Cost
111 | 2G | 53.00
112 | 7G | 25.00
112 | 7G | 25.00
113 | 8G | 20.00
113 | 8G | -20.00
114 | 9G | 15.00
115 | 2G | 53.00
115 | 2G | 53.00
115 | 2G | -53.00
Charge =
Case| Part_Number | Cost
111 | 2G | 53.00
112 | 7G | 25.00
112 | 7G | 25.00
113 | 8G | 20.00
114 | 9G | 15.00
115 | 2G | 53.00
115 | 2G | 53.00
Credits =
Case| Part_Number | Cost
113 | 8G | -20.00
115 | 2G | -53.00
Output =
df =
Case| Part_Number | Cost
111 | 2G | 53.00
112 | 7G | 25.00
112 | 7G | 25.00
114 | 9G | 15.00
115 | 2G | 53.00
See how it removed 113 since there was 1 charge and 1 credit but kept (1) of 115 since there were 2 charges and 1 credit.
uj5u.com熱心網友回復:
試試這個:
invoices = pd.DataFrame([['111', '2g', 53],
['112', '7g', 25],
['112', '7g', 25],
['113', '8g', 20],
['113', '8g', -20],
['114', '9g', 15],
['115', '2g', 53],
['115', '2g', 53],
['115', '2g', -53]],
columns=['Case', 'PartNo', 'Cost'])
print(f"Original invoices:\n{invoices}\n\n")
newInvoices = invoices.copy()
newInvoices['Charge_Credit'] = 0
for idx, case, part, cost, ch_cr in newInvoices.itertuples():
creditedDf = newInvoices[(newInvoices.Case == case) &
(newInvoices.PartNo == part) &
(newInvoices.Cost == -cost) &
(newInvoices.Charge_Credit != 'remove')]
if len(creditedDf):
newInvoices.loc[creditedDf.iloc[0].name, 'Charge_Credit'] = 'remove'
newInvoices = newInvoices[['Case', 'PartNo', 'Cost']][newInvoices.Charge_Credit != 'remove']
newInvoices.reset_index(drop=True, inplace=True)
print(f"New invoices:\n{newInvoices}\n")
![當使用 df1[~df1.isin(df2)].dropna() 問題](https://img.uj5u.com/2021/12/31/776bf3a68ef045c597453800876b4a7c.png)
uj5u.com熱心網友回復:
根據我的理解, outputdf 應該顯示尚未支付的發票,即使它是重復的,對嗎?我相信這是您正在尋找的代碼,稍后會對其進行解釋。
dfinvoice = pd.DataFrame(columns=['Case', 'PartNo', 'Cost'],
data=np.array([['111', '2g', 53],
['112', '7g', 25],
['112', '7g', 25],
['113', '8g', 20],
['113', '8g', -20],
['114', '9g', 15],
['115', '2g', 53],
['115', '2g', 53],
['115', '2g', -53]
]))
dfcharge = pd.DataFrame(columns=['Case', 'PartNo', 'Cost'],
data=np.array([['111', '2g', 53],
['112', '7g', 25],
['112', '7g', 25],
['113', '8g', 20],
['114', '9g', 15],
['115', '2g', 53],
['115', '2g', 53]
]))
dfcredits = pd.DataFrame(columns=['Case', 'PartNo', 'Cost'],
data=np.array([['113', '8g', -20],
['115', '2g', -53]
]))
dfowing = pd.DataFrame(columns=['Case', 'PartNo', 'Cost'],
data= np.array([['111', '2g', 53],
['112', '7g', 25],
['112', '7g', 25],
['114', '9g', 15],
['115', '2g', 53]
]))
df = dfinvoice
for x, y in df.iterrows():
for a, b in df.iterrows():
if y[0] == b[0]:
if x != a:
first = int(y[2])
second = int(b[2])
if first > 0 and second < 0:
print(x, y)
print('compared to')
print(a, b)
df = df.drop(x)
df = df.drop(a)
print(df)
dfowing 是資料框應該是什么樣子。我用它作為參考。
在 for 回圈中使用 for 回圈,您可以交叉參考您的值。x 和 a 是索引,y 和 b 是資料行。在第一個 if 陳述句中,我正在檢查發票編號是否匹配。在第二個 if 陳述句中,我必須確保索引不匹配,因此它會將自己與下一行進行比較,盡管不是完全必要的。第一個和最后一個是“成本”列中的值,在我的資料框中它們作為字串回傳,您不能比較整數和字串來檢查一個是大于還是小于 0。在最后一個 if 陳述句中檢查一個是大于 0 且 1 小于 0 并使用索引洗掉該行,用于洗掉df = df.drop()已收取發票然后貸記的每個匹配項。
我不是最擅長解釋這些事情的人,所以如果有人想編輯我的解釋,請隨意:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/398840.html
