2017-03-11 4 views
2

Lassen Sie uns sagen, dass ich mit Spalten a, b, c, d, e und ein Wörterbuch, einen Datenrahmen bekam {"A": "a", "B": "b", "E": "e"}Pandas: DIKT (einschließlich Betreiber) zurückzukehren Spalte Teilmenge von Datenrahmen

a) Wie verwende ich dieses Wörterbuch einen neuen Datenrahmen zurückzukehren (gleicher Index) mit nur diesen 3 Spalten (in Cap-Buchstaben umbenannt)?

b) Gibt es alternativ eine Möglichkeit, eine Spalte im ursprünglichen Datenrahmen zu löschen, die nicht im Wörterbuch aufgeführt ist und den ursprünglichen Datenrahmen im Grunde auf die Auswahl reduzieren? (mit umbenennen Spalten?)

Lassen Sie uns weiter sagen, ich hatte Wörterbuch {"A": "a", "Diff": "b - c", "Sum": "d + e"} Bezug auf die Spalten in meinem Datenrahmen, sondern auch einschließlich Operatoren (-, +).

c) Gibt es eine Möglichkeit, einen neuen Datenrahmen (gleicher Index) mit 3 neuen Spalten mit Daten aus meinem ursprünglichen Datenrahmen "aggregiert", wie von den Betreibern beschrieben, zurückzugeben?

Danke für Ihre Hilfe

Antwort

4

könnten Sie verwenden eval - nicht die Python-Funktion mit dem gleichen Namen, aber die DataFrame method.

In [50]: df = pd.DataFrame(np.arange(15).reshape((3,5)), columns=list("abcde")) 

In [51]: df 
Out[51]: 
    a b c d e 
0 0 1 2 3 4 
1 5 6 7 8 9 
2 10 11 12 13 14 

In [52]: d = {"A": "a", "B": "b", "C": "c"} 

In [53]: d2 = {"A": "a", "Diff": "b - c", "Sum": "d + e"} 

Mit dem Dataframe Konstruktor statt pd.concat auf einzelne Serie:

In [87]: pd.DataFrame({k: df.eval(v) for k,v in d.items()}) 
Out[87]: 
    A B C 
0 0 1 2 
1 5 6 7 
2 10 11 12 

In [88]: pd.DataFrame({k: df.eval(v) for k,v in d2.items()}) 
Out[88]: 
    A Diff Sum 
0 0 -1 7 
1 5 -1 17 
2 10 -1 27 
+0

Ich denke, wir können es tun, ohne 'pd.concat()' zu verwenden: 'df.eval ('\ n'.join ([' {} = {} '. Format (k, v) für k, v in d2 .items()]), inplace = False) ' – MaxU

+0

@MaxU: Ich denke, ich bevorzuge es, ein Diktat an DataFrame zu übergeben. Ich dachte, dass ich das ursprünglich ausprobiert habe und etwas mit den Seriennamen schief gelaufen ist, aber ich muss etwas falsch gemacht haben, denn es scheint jetzt zu funktionieren (?) .. – DSM

+0

AFAIK mit 'df.eval()' erlaubt uns nur mehrere Spalten hinzuzufügen wenn eine neue Spalte in einer neuen Zeile ist, daher '' n'.join (...) ' – MaxU

1

In Bezug auf Fragen a und b, wird die folgende Arbeiten:

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randn(4, 5), columns=list('abcde')) 

      a   b   c   d   e 
0 0.653701 -1.267756 0.680395 0.997065 1.389126 
1 -1.598463 2.595352 0.983189 -0.130996 0.605120 
2 0.631091 -1.293486 0.095808 -0.474806 -0.353356 
3 1.867020 2.164540 0.021103 1.810129 1.114983 

d = {"A": "a", "B": "b", "E": "e"} 

Dann wird für Python 2,

df[d.values()].rename(columns={v: k for k, v in d.items()}) 

und für Python 3.x (siehe MaxUs Kommentar)

df.loc[:, d.values()].rename(columns={v: k for k, v in d.items()}) 

geben Sie die gewünschte Ausgabe:

  A   B   E 
0 0.653701 -1.267756 1.389126 
1 -1.598463 2.595352 0.605120 
2 0.631091 -1.293486 -0.353356 
3 1.867020 2.164540 1.114983 
+0

Und ich nehme an, Sie 'df.query' für die dritte Frage –

+0

Bitte beachten Sie, dass diese Lösung funktioniert nicht unter Python 3.x verwenden könnten Verwenden Sie: 'df.loc [:, d.values ​​()]. ​​Rename (Spalten = {v: k für k, v in d.items()}) 'stattdessen – MaxU

+1

@MaxU: Danke, ich habe meinen Beitrag entsprechend bearbeitet (und auch deine, nette Lösung upvoted). – Cleb

2

Ich benutzte ein DF, generated by @DSM:

In [145]: d2 = {"A": "a", "Diff": "b - c", "Sum": "d + e"} 

In [146]: df 
Out[146]: 
    a b c d e 
0 0 1 2 3 4 
1 5 6 7 8 9 
2 10 11 12 13 14 

Multi-line-Abfragen ermöglichen es uns, mehrere Spalten hinzufügen DataFrame.eval() mit:

In [147]: df.eval('\n'.join(['{} = {}'.format(k,v) for k,v in d2.items()]), inplace=False) 
Out[147]: 
    a b c d e A Diff Sum 
0 0 1 2 3 4 0 -1 7 
1 5 6 7 8 9 5 -1 17 
2 10 11 12 13 14 10 -1 27 

HINWEIS: es wird nur in dem Fall arbeiten, wenn neue Spalten auf einer neuen Zeile

Erklärung erscheinen:

In [148]: print('\n'.join(['{} = {}'.format(k,v) for k,v in d2.items()])) 
A = a 
Diff = b - c 
Sum = d + e 

Sie auch neue Spalten in weiteren Berechnungen (achten Sie auf "new" Spalte) verwenden können, :

In [152]: d3 = {"Diff": "b - c", "Sum": "d + e", "new": "Sum - Diff"} 

In [153]: df.eval('\n'.join(['{} = {}'.format(k,v) for k,v in d3.items()]), inplace=False) 
Out[153]: 
    a b c d e Diff Sum new 
0 0 1 2 3 4 -1 7 8 
1 5 6 7 8 9 -1 17 18 
2 10 11 12 13 14 -1 27 28 
+0

Wow ... das ist beeindruckend! Nahm mich einen Moment um meinen Kopf zu wickeln ... in meinem Fall versuche ich jedoch, auf einen neuen Datenrahmen zu reduzieren, den ursprünglichen fallen zu lassen und nur mit den Daten zu arbeiten, die ich tatsächlich brauche ... was mich wundern lässt: vielleicht könnte ich nur die read_csv Funktion anweisen, nur die Daten/Spalten zu lesen, die ich brauche ... aber das ist für einen anderen Tag ... :-) Danke! – criga

Verwandte Themen