valores de sustracción en función de una variable que comienza por 'c desde un conjunto de datos transaccionalHola, tengo un marco de datos con una columna llamada 'Número de factura' (factura No, ejemplo 541431 ). Y otra columna llamada 'Stockcode'.
Cuando InvoiceNo comienza por una C (ejemplo C541433 ) y coincide con un StockCode anterior Tengo que cancelar la 'Cantidad' y / o el 'Precio unitario' de mi análisis . (Significa que un cliente DEVUELVE el artículo). Estoy tratando de hacer un análisis de RFM y un análisis de la cesta de mercado, pero primero, debo tener esto en cuenta primero. ¿Cómo puedo restar el total gastado por CustomerID en cantidad y precio unitario cuando devuelven un artículo (y tengo una fila con un Invoiceno que comienza por 'C').
¿Como puedó resolver esté problema? Tengo 500K + filas de datos transaccionales.
| Factura no | Número de inventario | Descripción | Cantidad | Fecha de la factura | Precio unitario | Identificación del cliente | País |
| 541431 | 23166 | BOTE DE ALMACENAMIENTO TOP DE CERÁMICA MEDIA | 74215 | 18/1/2011 10:01 | 1.04 | 12346 | Reino Unido |
| C541433 | 23166 | BOTE DE ALMACENAMIENTO TOP DE CERÁMICA MEDIA | -74215 | 18/1/2011 10:17 | 1.04 | 12346 | Reino Unido |
| 537626 | 85116 | SOPORTE DE LUZ CANDELABRA NEGRO | 12 | 12/12/2010 14:57 | 2.1 | 12347 | Islandia |
| 537626 | 22375 | BOLSA DE AIRE BOLSA VINTAGE JUEGO MARRÓN | 4 | 12/12/2010 14:57 | 4.25 | 12347 | Islandia |
| 537626 | 71477 | VIDRIO COLOR. SOPORTE ESTRELLA T-LUZ | 12 | 12/12/2010 14:57 | 3,25 | 12347 | Islandia |
| 537626 | 22492 | VINTAGE MINI PAINT SET | 36 | 12/12/2010 14:57 | 0.65 | 12347 | Islandia |
| 537626 | 22771 | PULSERA DESGUARDO ACRILICO EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22772 | PERILLA DE CAJA ROSA ACRILICO EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22773 | MANDO DIBUJO VERDE ACRÍLICO EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22774 | PERILLA DE CAJA ROJA ACRILICO EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22775 | PURPLE DRAWERKNOB ACRYLIC EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22805 | PUNTO DRAWER AZUL ACRÍLICO EDWARDIAN | 12 | 12/12/2010 14:57 | 1.25 | 12347 | Islandia |
| 537626 | 22725 | RELOJ DE ALARMA BAKELIKE CHOCOLATE | 4 | 12/12/2010 14:57 | 3.75 | 12347 | Islandia |
| 537626 | 22726 | RELOJ DE ALARMA BAKELIKE VERDE | 4 | 12/12/2010 14:57 | 3.75 | 12347 | Islandia |
| 537626 | 22727 | RELOJ DE ALARMA BAKELIKE ROJO | 4 | 12/12/2010 14:57 | 3.75 | 12347 | Islandia |
| 537626 | 22728 | RELOJ DE ALARMA BAKELIKE PINK | 4 | 12/12/2010 14:57 | 3.75 | 12347 | Islandia |
| 537626 | 22729 | ALARMA RELOJ BAKELIKE NARANJA | 4 | 12/12/2010 14:57 | 3.75 | 12347 | Islandia |
Re: valores de sustracción según una variable que comienza por 'c desde un conjunto de datos transaccionalA continuación se muestra una nueva versión que reconcilia completamente los datos en una sola pasada de la tabla de datos. Se tarda unos 30 segundos para procesar
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: valores de sustracción según una variable que comienza por 'c desde un conjunto de datos transaccionalGracias kevin Sí, incluiría ese 1 'izquierda' en la contabilidad.
@Kevin_Anderson escribió:
Hola, Alexllorens!
¿Es esto algo que haces una vez, o algo que haces repetidamente? Asumo que la respuesta es "repetidamente". Si es así, debes escribir un script JSL.
¿Es posible que un cliente devuelva menos de un pedido completo? En otras palabras, si un cliente pidió 50 unidades y devolvió 49, ¿desearía incluir el 1 resto en su contabilidad?
Re: valores de sustracción según una variable que comienza por 'c desde un conjunto de datos transaccionalNo entendí completamente todos los matices, específicamente lo que constituye la clave principal compuesta para identificar los registros que deben ajustarse, ni los ajustes que deben hacerse.
Pero puede ser que un desarrollo del código a continuación pueda hacerlo. No es una comparación justa, pero toma menos de un segundo hacer lo que hace:
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: valores de sustracción según una variable que comienza por 'c desde un conjunto de datos transaccionalA continuación se encuentra un script que toma los registros de UnBooking y elimina su cantidad de UnBooking del registro de reserva anterior para el StockCode dado. A continuación, establece la cantidad de UnBooking en cero. Si no se encuentra un registro de reserva anterior, se asume que el registro existió antes del inicio de esta tabla de datos, y establece la cantidad de UnBooking en cero.
El problema con este script es que no es muy eficiente. En los más de 54,000 registros, tomó mi antiguo sistema 55 minutos. Se podrían usar otras metodologías que aumentarían la velocidad, pero me esforcé por desarrollar algo que siguiera su metodología implícita.
El script también está incompleto en el tratamiento completo de la conciliación de los datos. Es decir, si la cantidad de UnBooking es 10 (en sus datos, -10) y la cantidad de la reserva anterior es 7, el script no toma los 3 productos no conciliados y continúa hacia atrás para encontrar el siguiente registro de reserva y resta los 3 productos no conciliados de esa reserva. Eso podría agregarse si decide implementar mi metodología.
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: valores de sustracción según una variable que comienza por 'c desde un conjunto de datos transaccionalHola, Alexllorens!
¿Es esto algo que haces una vez, o algo que haces repetidamente? Asumo que la respuesta es "repetidamente". Si es así, debes escribir un script JSL.
¿Es posible que un cliente devuelva menos de un pedido completo? En otras palabras, si un cliente pidió 50 unidades y devolvió 49, ¿desearía incluir el 1 resto en su contabilidad?