2016-08-05 158 views
1

我在分析美国的轮询数据,具体来说,我试图找出哪些国家是安全的,边缘的或者紧密的('紧密度')。我有一个调查结果的时间和他们的“亲密度”的数据框。我正在使用熊猫的声明来获得“亲密”条目的摘要。从熊猫系列中选择行是阵列的行

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) 

我试图从这个系列中进行选择,但是我无法正确地理解语法。例如,我想用这个语法只需选择“安全”的国家:

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

假设你有一个系列列表的数据帧,说:

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 

要找到那些其含你可以使用:

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

等等。由OP给出

0

数据帧样本:

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不,如果你按照op的方式去做,他会得到一系列值的系列,我会更新回答。 – shivsn

+0

让我们继续讨论[聊天](https://chat.stackoverflow.com/rooms/120309/selecting-rows-from-pandas-series-where-rows-are-arrays)。 –

0

我想用.unique()是构建系列s不是攻击这个问题的最好方法。改为使用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=' ')