2 votes

Répéter les lignes de l'image de données n fois en fonction des valeurs uniques des colonnes et créer une nouvelle colonne avec des valeurs différentes pour chaque ligne répétée.

Comme le titre l'indique, j'essaie d'obtenir un dataframe dont les lignes sont répétées. Le facteur qui détermine les N répétitions à effectuer est basé sur la longueur des valeurs uniques d'une colonne spécifique présente dans le cadre de données original. Une fois le processus de répétition effectué, j'aimerais créer une nouvelle colonne qui applique toutes les mêmes valeurs uniques de la colonne spécifique du cadre de données d'origine à chaque nouvelle ligne créée.

Je sais que c'est un peu confus, mais je ne peux pas essayer d'exposer mes doutes d'une meilleure façon. Ainsi, pour faciliter votre compréhension de l'approche que je souhaite adopter, voici un bref exemple de mon dataframe et du dataframe de sortie souhaité :

 >> Original Dataframe

       Samp     Age     Cs
 1       A      51      msi
 2       B      62      cin
 3       C      55      msi
 4       D      70      ebv
 5       E      56      gs
 ....

Comme vous pouvez le constater, mon Cs a 4 valeurs uniques (qui peuvent ne pas être les mêmes pour différents cadres de données). Mon objectif est donc d'obtenir un cadre de données ayant la structure suivante :

 >> Desired Dataframe

       Samp     Age     Cs
 1       A      51      msi
 1       A      51      cin
 1       A      51      ebv
 1       A      51      gs
 2       B      62      cin
 2       B      62      msi
 2       B      62      gs
 2       B      62      ebv
 3       C      55      msi
 3       C      55      cin
 3       C      55      ebv
 3       C      55      gs
 4       D      70      ebv
 4       D      70      cin
 4       D      70      msi
 4       D      70      gs
 5       E      56      gs
 5       E      56      cin
 5       E      56      msi
 5       E      56      ebv
 ....

Comme vous pouvez le voir, dans le cadre de données souhaité, toutes les lignes ont été répétées 4 fois (ce qui correspond au nombre de lignes uniques dans le cadre de données). Cs ) à l'exception des valeurs de la colonne Cs (qui applique toutes ses valeurs uniques à différentes lignes).

2voto

jpp Points 83462

Une solution consiste à convertir les 'Cs' à un Catégorique . Ensuite, utilisez GroupBy + first :

df['Cs'] = df['Cs'].astype('category')

res = df.groupby(['Samp', 'Cs']).first().reset_index()
res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)

Résultat

   Samp   Cs  Age
0     A  cin   51
1     A  ebv   51
2     A   gs   51
3     A  msi   51
4     B  cin   62
5     B  ebv   62
6     B   gs   62
7     B  msi   62
8     C  cin   55
9     C  ebv   55
10    C   gs   55
11    C  msi   55
12    D  cin   70
13    D  ebv   70
14    D   gs   70
15    D  msi   70
16    E  cin   56
17    E  ebv   56
18    E   gs   56
19    E  msi   56

1voto

Alex Points 608

Vous pouvez utiliser le pivot et ensuite fillna les deux façons de calculer votre résultat :

df.pivot('Cs', 'Samp', 'Age').fillna(method='ffill').fillna(method='bfill').unstack().to_frame('Age').reset_index()

1voto

user3483203 Points 28606

Créer un autre DataFrame en utilisant numpy.unique et effectuer une fusion, qui produira le produit cartésien des deux cadres.

s = pd.Series(np.unique(df.Cs.values)).rename('Cs').to_frame()

pd.merge(
    df.iloc[:, :2].assign(key=0),
    s.assign(key=0),
    on='key'
).drop('key', 1)

   Samp  Age   Cs
0     A   51  cin
1     A   51  ebv
2     A   51   gs
3     A   51  msi
4     B   62  cin
5     B   62  ebv
6     B   62   gs
7     B   62  msi
8     C   55  cin
9     C   55  ebv
10    C   55   gs
11    C   55  msi
12    D   70  cin
13    D   70  ebv
14    D   70   gs
15    D   70  msi
16    E   56  cin
17    E   56  ebv
18    E   56   gs
19    E   56  msi

Horaires

tmp = pd.DataFrame({
    'Samp': np.arange(10000),
    'Age': np.arange(10000),
    'Cs': np.repeat(df.Cs, 2000)
})

In [90]: %%timeit
    ...: s = pd.Series(np.unique(tmp.Cs.values)).rename('Cs').to_frame()
    ...: pd.merge(
    ...:     tmp.iloc[:, :2].assign(key=0),
    ...:     s.assign(key=0),
    ...:     on='key'
    ...: ).drop('key', 1)
    ...:
10.3 ms ± 92.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [91]: %%timeit
    ...: tmp['Cs'] = tmp['Cs'].astype('category')
    ...:
    ...: res = tmp.groupby(['Samp', 'Cs']).first().reset_index()
    ...: res['Age'] = res.groupby('Samp')['Age'].transform('first').astype(int)
    ...:
    ...:
51.5 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X