2016-08-05 4 views
1

Я пытаюсь проанализировать данные опроса США, в частности, я пытаюсь определить, какие государства безопасны, маргинальны или плотны («близость»). У меня есть dataframe с результатами опроса по времени и их «близостью». Я использую это утверждение Pandas, чтобы получить краткое изложение записей «близости».Выбор строк из серии Pandas, где строки являются массивами

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

Это дает мне эту серию (выбор, показанный для краткости):

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 

Строки массива типа, так что, например, s[0] дает:

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

I Я пытаюсь выбрать из этой серии, но я не могу получить синтаксис правильно. Например, я пытаюсь выбрать только «безопасные» государства, используя следующий синтаксис:

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

это не работает либо:

test[test == ['safe']) 

Вот что я хотел бы сделать: выбрать Государства, которые являются «маргинальными» или «жесткими», выбирают государства, которые являются «безопасными» и «безопасными» и т. Д. Кто-нибудь имеет представление о синтаксисе, который я должен использовать, или о лучшем подходе в первую очередь?

============ Вот пример данных перед 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

Вы можете разместить образец данных перед тем, как делать 'groupby'. – shivsn

+0

Спасибо shivsn - добавленный образец вопроса –

ответ

1

Скажем, у вас есть DataFrame с серией списков, скажем:

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

Тогда, чтобы увидеть, какие из них точно в безопасности, вы можете использовать:

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

чтобы найти те, которые вкл ude безопасно, вы можете использовать:

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

и так далее.

0

dataframe образец дается OP:

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 

затем с помощью grupby:

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

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

затем с помощью np.where:

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

Это дает мне пустую серию ... –

+0

@ AlbertoGarcia-Raboso Нет, если вы идете по пути, он получает серию с массивом значений, я обновляю ответ . – shivsn

+0

Продолжим эту дискуссию в [чате] (https://chat.stackoverflow.com/rooms/120309/selecting-rows-from-pandas-series-where-rows-are-arrays). –

0

Я думаю, что строительство серии s с помощью .unique() является не лучший способ атаковать эту проблему. Вместо этого попробуйте использовать 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) 

Выход:

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 

С одной стороны, это ct содержит точно такую ​​же информацию, как ваш s; с другой стороны, это делает тривиальным выбирать состояния так, как вы хотите.Два примера вы предложили:

# 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'] 

Или, используя, возможно, более читаемым .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'] 

Тем не менее, если вы решите использовать s, вот как вы можете построить ct из него:

ct = s.str.join(' ').str.get_dummies(sep=' ') 
Смежные вопросы