2016-12-15 35 views
0

环有一个多指标系列是这样的:熊猫我如何通过多指标系列

user_id cookie browser 
1  1_1  [chrome45] 
2  2_1  [IE 7] 
2  2_2  [IE 7, IE 8] 

有两个层次多指标本,user_idcookie。值是浏览器。

我想要做的是统计用户使用不同浏览器的次数。

因此对于这种情况下的用户1,他只使用了1个浏览器。但对于用户2,他用三种浏览器(IE7下不同的Cookie出现了两次,所以我数了两次,而不是一次),我怎么能循环通过它

,并得到这样的结果:

r = defaultdict(int) 

for user_id in multiIndex_series: 
    for cookie in multiIndex_series[user_id]: 
     r[user_id] += len(multiIndex_series[user_id][cookie]) # I don't know how to get user_id out of the MultiIndex series 

回答

1

您可以使用groupby与应用lambda函数从哪里得到压扁listslength - 见answer更多信息:

df = pd.DataFrame({'user_id':[1,2,2], 
        'cookie':['1_1','2_1','2_2'], 
        'browser':[['chrome45'],['IE 7'],['IE 7','IE 8']]}) 
df = df.set_index(['user_id','cookie']) 
print (df) 
        browser 
user_id cookie    
1  1_1  [chrome45] 
2  2_1   [IE 7] 
     2_2  [IE 7, IE 8] 

from itertools import chain 
print (df.groupby(level='user_id')['browser'] 
     .apply(lambda x: len(list(chain.from_iterable(x))))) 
user_id 
1 1 
2 3 
Name: browser, dtype: int64 

相反lambda可以使用自定义函数f用于测试什么更好的办法:

def f(x): 
    print (list(chain.from_iterable(x))) 
    return len(list(chain.from_iterable(x))) 

['chrome45'] 
['IE 7', 'IE 7', 'IE 8'] 

print (df.groupby(level='user_id')['browser'].apply(f)) 
user_id 
1 1 
2 3 
Name: browser, dtype: int64 

如果需要一系列的循环,一个可能的解决方案是:

for user_id, val in df['browser'].iteritems(): 
    print (user_id) 
    print (val) 

['chrome45'] 
(2, '2_1') 
['IE 7'] 
(2, '2_2') 
['IE 7', 'IE 8'] 
+0

感谢这么多的帮助!我不太明白的部分是'chain.from_iterable(x)'中的'x'。这种情况下'x'是什么?我尝试打印'x',我可以看到它是整个组。 'chain.from_iterable'如何具体挑选'browser'列? (因为'groupby(...)['browser']'部分?) – Cheng

+0

如果使用'df.groupby(level ='user_id')['browser']'然后应用某个函数,那么在每个循环在每个组的'x'变量df ['browser']中。最好的是在'f'函数中测试'def f(x):print(x)' – jezrael

+0

我几乎在multiIndex.series中为multiIndex.series.index.level [0]中的user_id做了这个操作[userid ]'。谢谢你救救我:) – Cheng