1
votes

Créer une nouvelle trame de données à partir de celles existantes sur la base d'un non logique

Je crois que mon problème est vraiment simple et qu'il doit y avoir un moyen très simple de résoudre ce problème, mais comme je suis assez nouveau avec Python, je ne pouvais pas le résoudre par ma propre solution élégante. Cette question est très probablement dupliquée, mais je ne l'ai pas trouvée, donc s'il vous plaît, si vous avez vu une autre question à mon problème, prenez-la comme une autre façon de développer.

Donc, disons que j'ai le dataframe suivant:

df1 = df.loc[(df['Column C'] == "Value_4")]

df2 = df.loc[(df['Column C'] == "Value_3")]

De là, je prends deux autres dataframes:

import pandas as pd
import matplotlib.pyplot as plt

data = {'Column A': [300,300,450,500,500,750,600,300,800],
'Column B': [1,1,2,2,3,3,0,2,3], 
'Column C': ["Value_1", "Value_2", "Value_3", "Value_4", "Value_1", 
"Value_2", "Value_3", "Value_4", "Value_5"]}
df = pd.DataFrame(data, columns=['Column A','Column B', 'Column C'])

Maintenant je veux créer un troisième dataframe (df3) qui est composé des lignes présentes dans df (dataframe existante) qui NE SONT PAS dans df1 et df2. Je ne veux pas extraire ou modifier quoi que ce soit sur le dataframe existant (df).

J'espère que j'ai réussi à être succinct et précis. J'apprécierais vraiment votre aide sur celui-ci!


0 commentaires

5 Réponses :


1
votes

Vous pouvez supprimer l'index de df2 + df3 de df.index et utiliser le diff pour réindexer df:

df.reindex(df.index.difference(df1.index.union(df2.index)))

    Column A    Column B    Column C
0   300         1           Value_1
1   300         1           Value_2
4   500         3           Value_1
5   750         3           Value_2
8   800         3           Value_5


0 commentaires

1
votes

Si je comprends bien, vous pouvez peut-être le faire en utilisant isin et le nier en utilisant ~ (il y a plusieurs façons d'accéder à votre solution, j'en publie une):

   Column A  Column B Column C
0       300         1  Value_1
1       300         1  Value_2
4       500         3  Value_1
5       750         3  Value_2
8       800         3  Value_5

Ce que nous faisons, c'est que nous vérifions les lignes de df qui ne sont pas dans df1 pour la colonne C, de même pour df et df2 avec la colonne C. Il vous reste d'autres lignes comme indiqué ci-dessous.

Sortie :

df3 = df.loc[~(df['Column C'].isin(df1['Column C'])) & ~(df['Column C'].isin(df2['Column C']))]


0 commentaires

1
votes

Utilisez Index.intersection avec Index.union et sélectionnez les lignes en DataFrame.loc :

s = df.merge(pd.concat([df1, df2]).drop_duplicates(), how='left', indicator=True)['_merge']

df3 = df[s == 'left_only']
print (df3)
   Column A  Column B Column C
0       300         1  Value_1
1       300         1  Value_2
4       500         3  Value_1
5       750         3  Value_2
8       800         3  Value_5

Une autre idée est d'utiliser Series.isin avec à la fois la valeur utilisée pour le filtrage et la condition d'inversion par ~ :

df3 = df[~df['Column C'].isin(['Value_4','Value_3'])]

Ou si besoin de tester toutes les colonnes par valeurs pour l'appartenance est possible, utilisez indicateur = True dans fusion avec concat a édité les deux DataFrames:

df3 = df.loc[df.index.difference(df1.index.union(df2.index))]
print (df3)
   Column A  Column B Column C
0       300         1  Value_1
1       300         1  Value_2
4       500         3  Value_1
5       750         3  Value_2
8       800         3  Value_5


0 commentaires

1
votes

Vous pouvez faire:

df3 = df.loc[~(df['Column C'] == "Value_4") & ~(df['Column C'] == "Value_3")]


0 commentaires

4
votes

Un moyen simple de le faire est:

  1. vous devez d'abord définir le nom de votre colonne sans espace.

  1. vous devez obtenir les valeurs uniques de Column_C pour df1 et df2 et créer liste .

    df3 = df[~df.Column_C.isin(l)]
    

  1. puis utilisez NOT IN avec df.

    l=[df1['Column_C'].unique()[0],df2['Column_C'].unique()[0]]
    


0 commentaires