2013-01-18 7 views
7

Ich versuche Pandas zu verwenden, um ein Problem zu lösen, das von einem Idioten DBA gemacht wird, der keine Sicherung eines jetzt abgestürzten Datensatzes macht, also versuche ich, Unterschiede zwischen zwei Spalten zu finden. Aus Gründen, auf die ich nicht eingehen werde, verwende ich Pandas statt einer Datenbank.Wie kann ich einen SQL-Stil disjunkten oder einen Unterschied für zwei Pandas DataFrame-Objekte festlegen?

Was ich gerne machen würde ist, gegeben:

Dataset A = [A, B, C, D, E] 
Dataset B = [C, D, E, F] 

Ich möchte Werte finden, die disjunkt sind.

In SQL ist dies Standard-Set-Logik, unterschiedlich je nach Dialekt, aber eine Standardfunktion erreicht. Wie verwende ich das elegant in Pandas? Ich würde gerne etwas Code eingeben, aber nichts, was ich habe, ist sogar im Entferntesten korrekt. Es ist eine Situation, in der ich nicht weiß, was ich nicht weiß ... Pandas hat Logik für Schnittpunkt und Vereinigung gesetzt, aber nichts für Disjunkt/Satzunterschied.

Danke!

Antwort

8

können Sie verwenden, um die set.symmetric_difference Funktion:

In [1]: df1 = DataFrame(list('ABCDE'), columns=['x']) 

In [2]: df1 
Out[2]: 
    x 
0 A 
1 B 
2 C 
3 D 
4 E 

In [3]: df2 = DataFrame(list('CDEF'), columns=['y']) 

In [4]: df2 
Out[4]: 
    y 
0 C 
1 D 
2 E 
3 F 

In [5]: set(df1.x).symmetric_difference(df2.y) 
Out[5]: set(['A', 'B', 'F']) 
+0

Danke, Das hat fantastisch funktioniert! – JPKab

0

Hier ist eine Lösung für mehrere Spalten, wahrscheinlich nicht sehr effizient, ich würde gerne ein Feedback auf machen diese schneller zu bekommen:

input = pd.DataFrame({'A': [1, 2, 2, 3, 3], 'B': ['a', 'a', 'b', 'a', 'c']}) 
limit = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']}) 


def set_difference(input_set, limit_on_set): 
    limit_on_set_sub = limit_on_set[['A', 'B']] 
    limit_on_tuples = [tuple(x) for x in limit_on_set_sub.values] 
    limit_on_dict = dict.fromkeys(limit_on_tuples, 1) 

    entries_in_limit = input_set.apply(lambda row: 
     (row['A'], row['B']) in limit_on_dict, axis=1) 

    return input_set[~entries_in_limit] 

>>> set_difference(input, limit) 

    item user 
1 a  2 
3 a  3 
Verwandte Themen