減去值取決於以事務數據集中的'c開頭的變量您好,我有一個名為'InvoiceNumber'列的數據框(invoiceNo,示例 541431 )。還有一個名為'Stockcode'的專欄。
當InvoiceNo以C開頭時(例子 C541433 )它匹配以前的StockCode 我必須從我的分析中取消'數量'和/或'單價' 。(這意味著客戶返回了該項目)。我正在嘗試進行RFM分析和市場籃子分析,但首先,我需要首先考慮這一點。當他們返回一個項目時,我怎樣才能減去每個CustomerID在Quantity和unitprice中的總花費(並且我有一行以'C'開頭的Invoiceno。
我怎麼解決這個問題?我有500K +行的交易數據。
| 發票號碼 | StockCode | 描述 | 數量 | 發票日期 | 單價 | 顧客ID | 國家 |
| 541431 | 23166 | 中型陶瓷頂級儲物罐 | 74215 | 18/1/2011 10:01 | 1.04 | 12346 | 英國 |
| C541433 | 23166 | 中型陶瓷頂級儲物罐 | -74215 | 18/1/2011 10:17 | 1.04 | 12346 | 英國 |
| 537626 | 85116 | 黑色CANDELABRA T-LIGHT HOLDER | 12 | 2010年7月12日14:57 | 2.1 | 12347 | 冰島 |
| 537626 | 22375 | AIRLINE BAG VINTAGE JET SET BROWN | 4 | 2010年7月12日14:57 | 4.25 | 12347 | 冰島 |
| 537626 | 71477 | 彩色玻璃。STAR T-LIGHT HOLDER | 12 | 2010年7月12日14:57 | 3.25 | 12347 | 冰島 |
| 537626 | 22492 | MINI PAINT SET VINTAGE | 36 | 2010年7月12日14:57 | 0.65 | 12347 | 冰島 |
| 537626 | 22771 | 清除抽屜KNOB亞克力EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22772 | PINK DRAWER KNOB ACRYLIC EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22773 | 綠色抽屜旋鈕EDRYIAN EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22774 | 紅色抽屜旋鈕EDRYIAN EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22775 | PURPLE DRAWERKNOB亞克力EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22805 | BLUE DRAWER KNOB ACRYLIC EDWARDIAN | 12 | 2010年7月12日14:57 | 1.25 | 12347 | 冰島 |
| 537626 | 22725 | 鬧鐘BAKELIKE巧克力 | 4 | 2010年7月12日14:57 | 3.75 | 12347 | 冰島 |
| 537626 | 22726 | 鬧鐘BAKELIKE GREEN | 4 | 2010年7月12日14:57 | 3.75 | 12347 | 冰島 |
| 537626 | 22727 | 鬧鐘BAKELIKE RED | 4 | 2010年7月12日14:57 | 3.75 | 12347 | 冰島 |
| 537626 | 22728 | 鬧鐘BAKELIKE PINK | 4 | 2010年7月12日14:57 | 3.75 | 12347 | 冰島 |
| 537626 | 22729 | 鬧鐘BAKELIKE ORANGE | 4 | 2010年7月12日14:57 | 3.75 | 12347 | 冰島 |
Re:根據從事務數據集中以'c開頭的變量來減去值下面是一個新版本,它在數據表的單次傳遞中完全協調數據。 處理大約需要30秒
Names Default To Here( 1 );
dt = Current Data Table();
// Add a RowNum column to permit the reordering back to
// the original order after processing
dt << New Column( "RowNum", formula( Row() ) );
dt:RowNum << delete property( "formula" );
// Sort the data so that processing can start at the
// top of the data, and flow downward, and the required
// data are grouped together and in row order
dt << Sort(
By( :CustomerID, :StockCode, :RowNum ),
Order( Ascending, Ascending, Descending ),
Replace Table( 1 )
);
// Find the starting row, that is, the first row with a
// CustomerID value
Start = 1;
While( Is Missing( dt:CustomerID[Start] ) == 1, Start++ );
// Loop across all rows, starting with the first non missing
// CustomerID
For( RowCNT = Start, RowCNT <= N Rows( dt ), RowCNT++,
// When the CustomerID or StockCode changes, or if this is
// the first loop, zero out the UnBookingAmount
If(
Try( :CustomerID[RowCNT - 1], "" ) != :CustomerID[RowCNT] |
Try( :StockCode[RowCNT - 1], "" ) != :StockCode[RowCNT] | RowCNT == Start,
UnBookingAmount = 0
);
// If this is a Change Invoice, then add the change to
// the running UnBookingAmount (Summing a negative amount actually makes
// the value of UnBookingAmount even more negative)
If( Starts With( :InvoiceNo[RowCNT], "C" ) == 1,
UnBookingAmount = Sum( UnBookingAmount, :Quantity[RowCNT] );
:Quantity[RowCNT] = 0;
, // Else
// Reduct the order by the current value of UnBookingAmount
:Quantity[RowCNT] = Sum( UnBookingAmount, :Quantity[RowCNT] );
// If the Quantity is less than zero, that means more
// UnBooking amount needs to be subtracted on earlier
// orders so reset the UnBookingAmountt remaining to be reconciled,
// and set the current order to 0
If( :Quantity[RowCNT] < 0,
UnBookingAmount = :Quantity[RowCNT];
:Quantity[RowCNT] = 0;
, // Else
// If the Quantity is >= 0 that means all UnBookings
// have been handled, so set the UnBookingAmount to 0
UnBookingAmount = 0
);
);
);
// Reorder the table back to the original order
dt << Sort( By( :RowNum ), Order( Ascending ), Replace Table( 1 ) );
// Delete the no longer needed RowNum column
dt << delete columns( "RowNum" );
Re:根據從事務數據集中以'c開頭的變量來減去值謝謝凱文!是的,我會在會計中包含1'左'
@Kevin_Anderson 中寫道:
嗨,Alexllorens!
這是你做過一次的事情,還是你反复做過的事情?我認為答案是“反复”的。 如果是這樣,您應該編寫JSL腳本。
客戶是否可以退回少於完整訂單?換句話說,如果客戶訂購了50個單位並返回了49個單位,您是否希望在會計中包含1個剩餘單位?
Re:根據從事務數據集中以'c開頭的變量來減去值我並沒有完全理解所有細微差別,特別是構成應該調整的記錄的複合主鍵是什麼,也不應該做出什麼調整。
但可能是下面的代碼的開發可以做到這一點。這不是一個公平的比較,但做它做的事情只需不到一秒鐘:
NamesDefaultToHere(1);
dt = DataTable("Original");
// Find and select all the rows for a cancelled transaction
dt << selectWhere(startsWith(:InvoiceNo, "C"));
// Put these transactions into another table
dt2 = dt << Subset(SelectedRows(1), Columns(:Stock Code, :Customer ID, :UnitPrice));
dt2 << setName("Cancelled");
// Delete the cancelled transactions in dt
dt << deleteRows;
// Join dt2 to dt
dt3 = dt << Join(
With( dt2 ),
By Matching Columns(
:StockCode = :StockCode,
:CustomerID = :CustomerID,
:UnitPrice = :UnitPrice
),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 0 ),
Preserve main table order( 1 ),
OutputTableName("Work with Me")
);
Close(dt, NoSave);
Close(dt2, NoSave);
Re:根據從事務數據集中以'c開頭的變量來減去值下面是一個獲取UnBooking記錄的腳本,並從給定StockCode的先前預訂記錄中刪除其UnBooking數量。 然後將UnBooking數量設置為零。 如果未找到先前的預訂記錄,則假設該記錄在該數據表開始之前存在,並將UnBooking的數量設置為零。
這個腳本的問題是效率不高。 在54,000多條記錄中,我的舊系統花了55分鐘。 可以使用其他可以提高速度的方法,但我努力開發出符合隱含方法的東西。
該腳本在完全處理數據協調方面也不完整。 也就是說,如果UnBooking數量為10(在您的數據中為-10)並且之前的預訂數量為7,則腳本不會採用3個未調整的產品並繼續向後查找下一個預訂記錄,並減去3個未調整的產品從那個預訂。 如果您選擇實施我的方法,可以添加。
Names Default To Here( 1 );
dt = Current Data Table();
// Record the starting time to allow the reporting of the amount of time it takes to
// perform all of the calculations
start = Today();
// Create a new column that represents the row number in the data table
dt << New Column( "RowNum", formula( Row() ) );
dt:RowNum << delete Property( "Formula" );
// Find all of the observations in the data table that are UnBookings
UnBookList = dt << get rows where( Uppercase( Left( :InvoiceNo, 1 ) ) == "C" & :Quantity < 0 );
// Loop across all of the UnBookings and subtract the UnBooking quantity from the
// Booking order record
For( corrections = 1, corrections <= N Rows( UnBookList ), corrections++,
// Print out the processing progress
If( Mod( corrections, 100 ) == 0,
time = Format( Today() - start, "hr:m:s" );
Show( time );
);
// Get the values of specific values for the current row being processed
curRowNum = UnBookList[corrections];
curCustomerID = dt:CustomerID[curRowNum];
curStockCode = dt:StockCode[curRowNum];
// Find the last row from the CustomerID's order for the StockCode being UnBooked
last row = Max( dt << get rows where( :quantity > 0 & curCustomerID == :CustomerID & curStockCode == :StockCode & :RowNum < curRowNum ) );
// If the record was found, then subtract (Sum the negative quantity) from the ordered quantity.
// Also, set the current rows quantity to zero
If( Is Missing( Last row ) == 0,
dt:Quantity[Last row] = Sum( dt:Quantity[Last row], dt:Quantity[curRowNum] );
);
// Set the current row's quantity value to zero
dt:Quantity[curRowNum] = 0;
);
// Print out the results
Show( N Rows( dt << get rows where( :quantity < 0 & Uppercase( Left( :InvoiceNo, 1 ) ) == "C" ) ) );
// Show the time it took to process the file
time = Format( Today() - start, "hr:m:s" );
Show( time );
// Delete the utility column RowNum
dt << Delete Columns( "RowNum" );
Re:根據從事務數據集中以'c開頭的變量來減去值嗨,Alexllorens!
這是你做過一次的事情,還是你反复做過的事情?我認為答案是“反复”的。 如果是這樣,您應該編寫JSL腳本。
客戶是否可以退回少於完整訂單?換句話說,如果客戶訂購了50個單位並返回了49個單位,您是否希望在會計中包含1個剩餘單位?