2016-08-05 4 views
1

Ich versuche, US-Abfragedaten zu analysieren, insbesondere versuche ich herauszufinden, welche Zustände sicher, marginal oder eng ("Nähe") sind. Ich habe einen Datenrahmen mit Umfrageergebnissen nach Zeit und ihrer 'Nähe'. Ich verwende diese Pandas-Anweisung, um eine Zusammenfassung der 'Nähe'-Einträge zu erhalten.Auswählen von Zeilen aus Pandas-Reihen, in denen Zeilen Arrays sind

s=self.daily.groupby('State')['closeness'].unique() 

Dies gibt mir diese Serie (Auswahl der Kürze halber gezeigt):

State 
AK      [safe] 
AL      [safe] 
CA      [safe] 
CO [safe, tight, marginal] 
FL   [marginal, tight] 
IA [safe, tight, marginal] 
ID      [safe] 
IL      [safe] 
IN    [tight, safe] 
Name: closeness, dtype: object 

die Zeilen vom Typ Array ist, so zum Beispiel s[0] gibt:

array(['safe'], dtype=object) 

I Ich versuche aus dieser Serie auszuwählen, aber ich kann die Syntax nicht richtig machen. Zum Beispiel versuche ich nur die ‚sicheren‘ Staaten mit folgenden Syntax wählen:

ipdb> s[s == 'safe'] 
*** ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

dies funktioniert auch nicht:

test[test == ['safe']) 

Hier ist, was würde ich tun: wählen Staaten, die "marginal" oder "eng" sind, wählen Staaten aus, die "sicher" und nur "sicher" sind und so weiter. Hat jemand eine Vorstellung von der Syntax, die ich verwenden sollte, oder von einem besseren Ansatz?

============ Hier ist eine Probe der Daten vor dem groupby:

ipdb> self.daily.head(3) 
     Date Democratic share Margin Method Other share \ 

0 2008-11-04   0.378894 -0.215351 Election  0.026861 
1 2008-11-04   0.387404 -0.215765 Election  0.009427 
2 2008-11-04   0.388647 -0.198512 Election  0.024194 

    Republican share State closeness  winner 
0   0.594245 AK  safe Republican 
1   0.603169 AL  safe Republican 
+0

können Sie vor dem 'groupby' Beispieldaten bereitstellen. – shivsn

+0

Danke shivsn - Probe zur Frage hinzugefügt –

Antwort

1

Sagen Sie bitte mit einer Reihe von Listen einen Datenrahmen haben, sagen:

df = pd.DataFrame({'a': [['safe'], ['safe', 'tight'], []]}) 

dann zu sehen, welche genau sicher sind, können Sie verwenden:

In [7]: df.a.apply(lambda x: x == ['safe']) 
Out[7]: 
0  True 
1 False 
2 False 
Name: a, dtype: bool 

diejenigen zu finden, die incl ude sicher, können Sie verwenden:

In [9]: df.a.apply(lambda x: 'safe' in x) 
Out[9]: 
0  True 
1  True 
2 False 
Name: a, dtype: bool 

und so weiter.

0

Datenrahmen Probe von OP gegeben:

In[66]:df 
Out[66]: 
     Date Democratic share Margin Method Other share 0 2008-11-04   0.378894 -0.215351 Election  0.026861 
1 2008-11-04   0.387404 -0.215765 Election  0.009427 
2 2008-11-04   0.388647 -0.198512 Election  0.024194 
3 2008-11-04   0.384547 -0.194545 Election  0.024194 
4 2008-11-04   0.345330 -0.194512 Election  0.024459 

    Republican share State closeness  winner 
0   0.594245 AK  safe Republican 
1   0.603169 AL  safe Republican 
2   0.454545 CA  tight Democratic 
3   0.453450 CO marginal Democratic 
4   0.454545 FL  tight Republic 

dann durch grupby mit:

In[67]:s=df.groupby('State')['closeness'].unique() 

In[68]:s 
Out[68]: 
State 
AK  [safe] 
AL  [safe] 
CA  [tight] 
CO [marginal] 
FL  [tight] 

dann np.where mit:

In[69]:s.ix[np.where(s=='safe')] 
Out[69]: 
State 
AK [safe] 
AL [safe] 
Name: closeness, dtype: object 
+0

Das gibt mir eine leere Serie ... –

+0

@ AlbertoGarcia-Raboso Nein, es ist nicht, wenn Sie auf dem Weg gehen, er bekommt eine Reihe mit Array von Werten, werde ich aktualisieren Antworten . – shivsn

+0

Lassen Sie uns diese Diskussion in [Chat] (https://chat.stackoverflow.com/rooms/120309/selecting-rows-from-pandas-series-whererows-are-arrays) fortsetzen. –

0

Ich denke, die Serie der Konstruktion s unter Verwendung .unique() ist nicht der beste Weg, dieses Problem anzugehen. Verwenden Sie stattdessen pd.crosstab.

import pandas as pd 

daily = pd.DataFrame({'State': ['AK', 'AL', 'CA', 'CO', 'CO', 'CO', 'FL', 
           'FL', 'IA', 'IA', 'IA', 'ID', 'IL', 'IN', 'IN'], 
         'closeness': ['safe', 'safe', 'safe', 'safe', 'tight', 
            'marginal', 'marginal', 'tight', 'safe', 
            'tight', 'marginal', 'safe', 'safe', 
            'tight', 'safe']}) 
ct = pd.crosstab(daily['State'], daily['closeness']) 
print(ct) 

Ausgang:

closeness marginal safe tight 
State       
AK    0  1  0 
AL    0  1  0 
CA    0  1  0 
CO    1  1  1 
FL    1  0  1 
IA    1  1  1 
ID    0  1  0 
IL    0  1  0 
IN    0  1  1 

Einerseits ist diese ct genau nach s die gleichen Informationen enthält; Auf der anderen Seite ist es trivial, die Zustände so auszuwählen, wie Sie es möchten.Die beiden Beispiele, die Sie vorgeschlagen:

# states that are 'marginal' or 'tight' 
print(ct.loc[(ct['marginal'] > 0) | (ct['tight'] > 0)] 
     .index.values) 
# => ['CO', 'FL', 'IA', 'IN'] 

# States that are 'safe' and only 'safe' 
print(ct.loc[(ct['safe'] > 0) & (ct['marginal'] == 0) & (ct['tight'] == 0)] 
     .index.values) 
# => ['AK', 'AL', 'CA', 'ID', 'IL'] 

Oder mit der vielleicht besser lesbar .query():

# states that are 'marginal' or 'tight' 
print(ct.query('marginal > 0 | tight > 0').index.values) 
# => ['CO', 'FL', 'IA', 'IN'] 

# States that are 'safe' and only 'safe' 
print(ct.query('safe > 0 & marginal == 0 & tight == 0') 
     .index.values) 
# => ['AK', 'AL', 'CA', 'ID', 'IL'] 

Aber wenn Sie darauf bestehen, Ihre s auf verwenden, hier ist, wie Sie ct daraus konstruieren können:

ct = s.str.join(' ').str.get_dummies(sep=' ') 
Verwandte Themen