2017-08-08 1 views
4

ich Pandas Datenrahmen, die wie die folgenden und hält Gruppen von Daten über eine Spalte id aussieht:Demontieren des Datenrahmens in neue Datenfelder von Teilmengen/Gruppen bzw. Erstellen neuer Datenrahmen von Datenuntermengen/Gruppen aus anderen Datenrahmen

import numpy as np 
import pandas as pd 


df = pd.DataFrame(np.random.randn(10, 4), columns=list('ABCD')) 
df['id'] = ['W', 'W', 'W', 'Z', 'Z', 'Y', 'Y', 'Y', 'Z', 'Z'] 

print(df) 

      A   B   C   D id 
0 0.347501 -1.152416 1.441144 -0.144545 w 
1 0.775828 -1.176764 0.203049 -0.305332 w 
2 1.036246 -0.467927 0.088138 -0.438207 w 
3 -0.737092 -0.231706 0.268403 0.464026 x 
4 -1.857346 -1.420284 -0.515517 -0.231774 x 
5 -0.970731 0.217890 0.193814 -0.078838 y 
6 -0.318314 -0.244348 0.162103 1.204386 y 
7 0.340199 1.074977 1.201068 -0.431473 y 
8 0.202050 0.790434 0.643458 -0.068620 z 
9 -0.882865 0.687325 -0.008771 -0.066912 z 

Jetzt möchte ich schaffen neue Datenrahmen (mit dem Namen df_w , df_x, df_y, df_z), die nur ihre Daten von dem ursprünglichen Datenrahmen halten und optimal innerhalb einiger iterabler, z eine Liste:

df_w 

      A   B   C   D id 
0 0.347501 -1.152416 1.441144 -0.144545 w 
1 0.775828 -1.176764 0.203049 -0.305332 w 
2 1.036246 -0.467927 0.088138 -0.438207 w 

df_x 

      A   B   C   D id 
0 -0.737092 -0.231706 0.268403 0.464026 x 
1 -1.857346 -1.420284 -0.515517 -0.231774 x 

df_y 

      A   B   C   D id 
0 -0.970731 0.217890 0.193814 -0.078838 y 
1 -0.318314 -0.244348 0.162103 1.204386 y 
2 0.340199 1.074977 1.201068 -0.431473 y 

df_z 

      A   B   C   D id 
0 0.202050 0.790434 0.643458 -0.068620 z 
1 -0.882865 0.687325 -0.008771 -0.066912 z 

Gibt es einen intelligenten (vektorisiert Pandas) Weg, um diese mit groupby zu erreichen, anzuwenden und/oder applymap und eine Funktion?

ich Iterieren über den Datenrahmen dachte, aber es scheint nicht sehr elegant zu sein ..

Vielen Dank im Voraus für alle Hinweise!

Antwort

6

können wir ein Diktat von DFs erstellen:

In [166]: dfs = {k:v for k,v in df.groupby('id')} 

In [168]: dfs.keys() 
Out[168]: dict_keys(['W', 'Y', 'Z']) 

In [169]: dfs['W'] 
Out[169]: 
      A   B   C   D id 
0 -0.373021 -0.555218 0.022980 -0.512323 W 
1 -1.599466 0.637292 0.045059 -0.334030 W 
2 0.100659 0.557068 0.142226 -0.186214 W 

In [170]: dfs['Y'] 
Out[170]: 
      A   B   C   D id 
5 0.540107 -0.739077 0.992408 2.010203 Y 
6 -0.201376 -0.913222 -0.173284 1.837442 Y 
7 -1.367659 0.915360 0.072720 -0.886071 Y 

In [171]: dfs['Z'] 
Out[171]: 
      A   B   C   D id 
3 -0.329087 0.842431 0.839319 -0.597823 Z 
4 -0.594375 -0.950486 1.125584 0.116599 Z 
8 0.366667 -0.978279 -1.449893 0.192451 Z 
9 -0.007439 -0.084612 0.010192 -0.417602 Z 

UPDATE: mit Reset-Index:

In [177]: {k:v.reset_index(drop=True) for k,v in df.groupby('id')} 
Out[177]: 
{'W':   A   B   C   D id 
0 -0.373021 -0.555218 0.022980 -0.512323 W 
1 -1.599466 0.637292 0.045059 -0.334030 W 
2 0.100659 0.557068 0.142226 -0.186214 W, 
'Y':   A   B   C   D id 
0 0.540107 -0.739077 0.992408 2.010203 Y 
1 -0.201376 -0.913222 -0.173284 1.837442 Y 
2 -1.367659 0.915360 0.072720 -0.886071 Y, 
'Z':   A   B   C   D id 
0 -0.329087 0.842431 0.839319 -0.597823 Z 
1 -0.594375 -0.950486 1.125584 0.116599 Z 
2 0.366667 -0.978279 -1.449893 0.192451 Z 
3 -0.007439 -0.084612 0.010192 -0.417602 Z} 
+1

Das Zurücksetzen des Indexes über 'v.reset_index (inplace = True)' würde das gewünschte Ergebnis erzeugen. Danke vielmals! Unglaublich, wie schnell du bist. –

+1

'{k: v.reset_index (drop = True) für k, v in df.groupby ('id')}' für Null-Start-Indizes. – Zero

+0

ja, danke Jungs! Ich habe die Antwort aktualisiert – MaxU

3

Ich denke, die beste schaffen dict von convert groupby Objekt tuples und dann zu dict:

#for index starts from 0 
df.index = df.groupby('id').cumcount() 

dfs = dict(tuple(df.groupby('id'))) 
print (dfs) 
{'W':   A   B   C   D id 
0 1.331587 0.715279 -1.545400 -0.008384 W 
1 0.621336 -0.720086 0.265512 0.108549 W 
2 0.004291 -0.174600 0.433026 1.203037 W, 'Y': A B   C   D id 
0 -1.977728 -1.743372 0.266070 2.384967 Y 
1 1.123691 1.672622 0.099149 1.397996 Y 
2 -0.271248 0.613204 -0.267317 -0.549309 Y, 'Z': A B   C   D id 
0 -0.965066 1.028274 0.228630 0.445138 Z 
1 -1.136602 0.135137 1.484537 -1.079805 Z 
2 0.132708 -0.476142 1.308473 0.195013 Z 
3 0.400210 -0.337632 1.256472 -0.731970 Z} 

print (dfs['Y']) 
      A   B   C   D id 
0 -1.977728 -1.743372 0.266070 2.384967 Y 
1 1.123691 1.672622 0.099149 1.397996 Y 
2 -0.271248 0.613204 -0.267317 -0.549309 Y 

Für interessante mögliche Datenrahmen Namen Verwendung Brauch ist durch globals, aber besser ist dict:

for i, df in df.groupby('id'): 
    globals()['df_' + i] = df.reset_index(drop=True) 

print (df_Y) 
      A   B   C   D id 
0 -1.977728 -1.743372 0.266070 2.384967 Y 
1 1.123691 1.672622 0.099149 1.397996 Y 
2 -0.271248 0.613204 -0.267317 -0.549309 Y 
+0

Wow, das war unglaublich schnell. Ich mag die Lösung sehr! Gibt es eine Möglichkeit, den Index auch "on the fly" zurückzusetzen, damit die Subframes mit "0" beginnen? –

+0

Ja, es ist möglich durch Änderungsindex vorher. – jezrael

+1

Danke an euch beide! –

Verwandte Themen