soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelBonjour, j'ai un dataframe avec une colonne nommée 'InvoiceNumber' (invoiceNo, example 541431 ). Et une autre colonne nommée 'Stockcode'.
Quand InvoiceNo commence par un C (exemple C541433 ) et correspond à un StockCode précédent Je dois annuler la "quantité" et / ou le "prix unitaire" de mon analyse . (Cela signifie qu'un client a retourné l'article). J'essaie de faire une analyse RFM et une analyse du panier de marché, mais je dois d'abord en tenir compte. Comment puis-je soustraire le total dépensé par CustomerID en quantité et en prix unitaire lorsqu'ils renvoient un article (et que j'ai une ligne avec un Invoiceno commençant par 'C'.
Comment puis-je résoudre ce problème? J'ai 500K + lignes de données transactionnelles.
| FactureNo | StockCode | La description | Quantité | Date de facture | Prix unitaire | N ° de client | Pays |
| 541431 | 23166 | Bocal de stockage supérieur en céramique | 74215 | 18/1/2011 10:01 | 1.04 | 12346 | Royaume-Uni |
| C541433 | 23166 | Bocal de stockage supérieur en céramique | -74215 | 18/1/2011 10:17 | 1.04 | 12346 | Royaume-Uni |
| 537626 | 85116 | SUPPORT DE T-LUMIÈRE CANDELABRA NOIR | 12 | 12/07/2010 14:57 | 2.1 | 12347 | Islande |
| 537626 | 22375 | AIRLINE BAG VINTAGE JET SET BRUN | 4 | 12/07/2010 14:57 | 4,25 | 12347 | Islande |
| 537626 | 71477 | COULEUR VERRE. PORTE-ÉCLAIRAGE STAR | 12 | 12/07/2010 14:57 | 3,25 | 12347 | Islande |
| 537626 | 22492 | MINI PAINT SET VINTAGE | 36 | 12/07/2010 14:57 | 0,65 | 12347 | Islande |
| 537626 | 22771 | BOUTON DE TIROIR CLAIR ACRYLIQUE EDWARDIAN | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22772 | BOUTON DE TIROIR ROSE ACRYLIQUE EDWARDIEN | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22773 | BOUTON DE TIROIR VERT ACRYLIQUE EDWARDIEN | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22774 | BOUTON DE TIROIR ROUGE ACRYLIQUE EDWARDIEN | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22775 | EDWARDIEN ACRYLIQUE ACRYLIQUE À TUYAUX | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22805 | BOUTON DE TIROIR BLEU ACRYLIQUE EDWARDIEN | 12 | 12/07/2010 14:57 | 1,25 | 12347 | Islande |
| 537626 | 22725 | CHOCOLAT BAKELIKE D'HORLOGE | 4 | 12/07/2010 14:57 | 3,75 | 12347 | Islande |
| 537626 | 22726 | Réveil Alarme Vert Boulangerie | 4 | 12/07/2010 14:57 | 3,75 | 12347 | Islande |
| 537626 | 22727 | BAKELIKE ROUGE D'ALARME | 4 | 12/07/2010 14:57 | 3,75 | 12347 | Islande |
| 537626 | 22728 | Réveil BAKELIKE ROSE | 4 | 12/07/2010 14:57 | 3,75 | 12347 | Islande |
| 537626 | 22729 | BAKELIKE ORANGE Réveil | 4 | 12/07/2010 14:57 | 3,75 | 12347 | Islande |
Re: soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelVous trouverez ci-dessous une nouvelle version qui réconcilie complètement les données en un seul passage de la table de données. Il faut environ 30 secondes pour traiter
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: soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelMerci Kevin! oui j'inclurais que 1 'gauche' dans la comptabilité
@ Kevin_Anderson a écrit:
Salut Alexllorens!
Est-ce quelque chose que vous faites une fois ou quelque chose que vous faites à plusieurs reprises? Je suppose que la réponse est "à plusieurs reprises". Si c'est le cas, vous devriez écrire un script JSL.
Est-il possible qu'un client retourne moins qu'une commande complète? En d'autres termes, si un client commandait 50 unités et en renvoyait 49, voudriez-vous inclure le reste dans votre comptabilité?
Re: soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelJe n'ai pas bien compris toutes les nuances, en particulier ce qui constitue la clé primaire composite pour identifier les enregistrements à ajuster, ni les ajustements à effectuer.
Mais il se peut qu'un développement du code ci-dessous puisse le faire. Ce n'est pas une comparaison juste, mais cela prend moins d'une seconde pour faire ce qu'il fait:
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: soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelVous trouverez ci-dessous un script qui extrait les enregistrements UnBooking et supprime leur quantité UnBooking de l’enregistrement de réservation précédent pour le StockCode donné. Il règle ensuite la quantité de UnBooking à zéro. Si aucun enregistrement de réservation précédent n’est trouvé, on suppose que l’enregistrement existait avant le début de cette table de données et définit la quantité de la réservation en cours à zéro.
Le problème avec ce script est qu'il n'est pas très efficace. Sur les 54 000 enregistrements et plus, mon ancien système a pris 55 minutes. D'autres méthodes pourraient être utilisées pour augmenter la vitesse, mais je me suis efforcé de développer quelque chose qui suivrait votre méthodologie implicite.
Le script est également incomplet en ce qui concerne la réconciliation des données. Autrement dit, si la quantité de réservation est 10 (dans vos données, -10) et que la quantité de réservation précédente est de 7, le script ne prend pas les 3 produits non rapprochés et continue en arrière pour trouver le prochain enregistrement de réservation et soustrait les 3 produits non rapprochés. de cette réservation. Cela pourrait être ajouté si vous choisissez de mettre en œuvre ma méthodologie.
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: soustraction de valeurs dépendant d'une variable commençant par 'c à partir d'un jeu de données transactionnelSalut Alexllorens!
Est-ce quelque chose que vous faites une fois ou quelque chose que vous faites à plusieurs reprises? Je suppose que la réponse est "à plusieurs reprises". Si c'est le cas, vous devriez écrire un script JSL.
Est-il possible qu'un client retourne moins qu'une commande complète? En d'autres termes, si un client commandait 50 unités et en renvoyait 49, voudriez-vous inclure le reste dans votre comptabilité?