Dernières 30 pièces pour chaque ligne et supprimez les autres donnéesBonjour à tous,
J'ai une table de données qui comporte plusieurs colonnes et chaque colonne contient un nombre différent de lignes contenant des données. J'essaie de trouver un moyen d'obtenir les 30 dernières lignes de données dans chaque colonne. Par exemple, la colonne 1 comporte 50 lignes et la colonne 2 comporte 75 lignes et je souhaite que chaque ligne contienne les 30 dernières lignes d'informations. Existe-t-il un script qui puisse faire ça ?
Automatisation et scriptsMélange et nettoyage des donnéesPersonnalisation de masseRe : Dernières 30 pièces pour chaque ligne et supprimer les autres donnéesPour les futurs lecteurs de ce morceau, une correction à @Mark_Bailey La déclaration concernant son code par rapport au deuxième morceau de code de la réponse @txnelson doit être clarifiée.Les deux morceaux de code produiront les mêmes résultats si l'on suppose qu'une fois qu'une valeur manquante est trouvée, aucune valeur supplémentaire non manquante n'apparaît dans la colonne.@Mark_Bailey le code nécessite qu'il existe un nombre minimum de valeurs non manquantes, là où le code @txnelson ne le fait pas
Re : Dernières 30 pièces pour chaque ligne et supprimer les autres donnéesFWIW, voici encore une autre version utilisant des matrices :
NamesDefaultToHere(1);
// Make a data table 'dt', to play with.
nr = 100; // Number of rows
nc = 30; // Number of columns
p = 0.7; // Proportion of missing values
vals = J(nr*nc, 1, RandomInteger(0, 99));
makeMissing = RandomIndex(nr*nc, Floor(nr*nc*p));
vals[makeMissing] = .;
dt = AsTable(Shape(vals, nr, nc));
dt << setName("Random Integers with some missing");
// Start here with the current table . . .
lastN = 30; // Number of non-missing values to retain
dt = CurrentDataTable();
vals = dt << getAsMatrix;
// Loop over columns . . .
newVals = [];
for(c=1, c<=NCol(vals), c++,
NMV = vals[LocNonMissing(vals[0, c]), c]; // Non-mising values in this column
if(NRow(NMV) >= lastN, // Do we have enough non-missing values?
lastNMV = NMV[(NRow(NMV) - lastN + 1)::NRow(NMV)]; // If so, get the 'lastN' of these . . .
newVals = newVals||lastNMV; // . . . and add them into a new column
);
);
dt2 = AsTable(newVals);
dt2 << setName("Last "||Char(lastN)||" non-missing Random Integers");Re : Dernières 30 pièces pour chaque ligne et supprimer les autres donnéesEssayez cette version.
Names Default to Here( 1 );
// create the example
dt = New Table( "Odd Lengths",
New Column( "Column 1", Numeric, Continuous, Values( 1::50 ) ),
New Column( "Column 2", Numeric, Continuous, Values( 1::75 ) ),
New Column( "Column 3", Numeric, Continuous, Values( 1::28 ) )
);
Wait( 0 );
// process the data table
For( col = N Col( dt ), col > 0, col--,
values = Column( dt, col ) << Get Values;
not missing = Sum( Not( Is Missing( values ) ) );
If( not missing < 30,
dt << Delete Columns( Column( dt, col ) ),
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Re : Dernières 30 pièces pour chaque ligne et supprimer les autres données@Mark_Bailey Cela fonctionne très bien ! J'ai réalisé que j'avais des données dans des colonnes inférieures à 30 et supérieures à 30. Existe-t-il un moyen simple de n'afficher que cela ? Un exemple la colonne 1 a 50 lignes et la colonne 2 a 75 lignes et la colonne 3 a 28 lignes et je veux que chaque ligne ait les 30 dernières lignes d'informations, rien qui soit inférieur à 30, donc si elle a 29 points de données ou moins, je voudrais le supprimer aussi. Merci pour l'aide!
Re : Dernières 30 pièces pour chaque ligne et supprimer les autres donnéesVoici une autre version pour obtenir le même résultat que la deuxième solution de @txnelson
For( col = 1, col <= N Col( dt ), col++,
values = Column( dt, col ) << Get Values;
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Re : Dernières 30 pièces pour chaque ligne et supprimer les autres donnéesSupprimer toutes les lignes d'un tableau de données, sauf les 30 dernières, est simple.
Names Default To Here( 1 );
dt = Current Data Table();
dt << select where( Row() > N Rows( dt ) - 30 );
dt << delete rows;
Si vous demandez de trouver les 30 derniers points de données non manquants pour chaque colonne, puis de les enregistrer sous n colonnes par 30 lignes de données, c'est un peu plus difficile et je remettrai en question la validité de cette opération.Le résultat serait de supprimer pratiquement toute relation entre les points de données entre les différentes colonnes.
Names Default To Here( 1 );
dt = Current Data Table();
// Copy the data table retaining no rows;
dtCopy = dt << subset( selected rows( 0 ), selected columns( 0 ) );
dtCopy << select where( Row() >= 0 );
dtCopy << delete rows;
For( i = 1, i <= N Cols( dtCopy ), i++,
theList = {};
For( k = N Rows( dt ), k >= 1, k--,
If( Is Missing( Column( dt, i )[k] ) == 0,
Insert Into( theList, Column( dt, i )[k] );
If( N Items( theList ) >= 30,
Break()
);
)
);
Column( dtCopy, i ) << set values( Reverse( theList ) );
);