2016-07-13 51 views
3

我有一系列不規則數量的數據,我需要使用熊貓來確定跨多個柱子的分割部分的最常見值。我的意思的例子,如果我有什麼樣的奶酪我的同事曾與他們的午餐,每天的信息:熊貓中多個柱子的最常見值

Idx Name Cheese1 Cheese2 Cheese3 
0 Evan Gouda  NaN  NaN 
1 John Cheddar Havarti Blue 
2 Evan Cheddar Gouda  NaN 
3 John Havarti Swiss  NaN 

我正在尋找某種功能,這將使所產生的數據透視表:

Name Cheese Pct 
Evan Gouda  .66 
John Havarti .4 

我也不知道每次運行腳本時需要包含多少列,只是它們都是格式「Cheese」+索引。如果John在第二天出現四個奶酪,我將需要添加第四列,並且分析腳本需要能夠處理該問題。

回答

4
import io 
import pandas as pd 

data = io.StringIO("""\ 
Idx Name Cheese1 Cheese2 Cheese3 
0 Evan Gouda  NaN  NaN 
1 John Cheddar Havarti Blue 
2 Evan Cheddar Gouda  NaN 
3 John Havarti Swiss  NaN 
4 Rick NaN  NaN  NaN 
""") 
df = pd.read_csv(data, delim_whitespace=True) 

def top_cheese(g): 
    cheese_cols = [col for col in g.columns if col.startswith('Cheese')] 
    try: 
     out = (g[cheese_cols].stack().value_counts(normalize=True) 
          .reset_index().iloc[0]) 
     out.index = ['Cheese', 'Pct'] 
     return out 
    except IndexError: 
     return pd.Series({'Cheese': 'None', 'Pct': 0}) 


output = df.groupby('Name').apply(top_cheese) 
print(output) 

輸出:

 Cheese  Pct 
Name     
Evan Gouda 0.666667 
John Havarti 0.400000 
Rick  None 0.000000 
+3

你錯過了一個命名函數'big_cheese'的機會 – piRSquared

+0

這可以工作,但是當所有的人都有相同的最常見的奶酪時,它就會中斷。相反,它將名稱作爲列標題而不是索引。有什麼辦法解決這個問題嗎? – user3329648

+0

我通過使用try-except語句來修復它,以獲得索引或列名稱,但它很笨拙,如果有人有一個更好的解決方案,我想要一個更好的解決方案。 – user3329648

0

最近,我一直在使用R頗有幾分那裏我會解決這個問題,如:

library(data.table) 
library(dplyr) 
library(tidyr) 

x <- fread(' 
Idx Name Cheese1 Cheese2 Cheese3 
0 Evan Gouda  NaN  NaN 
1 John Cheddar Havarti Blue 
2 Evan Cheddar Gouda  NaN 
3 John Havarti Swiss  NaN', na = 'NaN') 

gather(x, , Cheese, matches('Cheese'), na.rm = T) %>% 
    group_by(Name, Cheese) %>% 
    summarise(n = n()) %>% 
    group_by(Name) %>% 
    mutate(p = n/sum(n)) %>% 
    filter(p == max(p)) %>% 
    select(-n) 

,輸出:

Name Cheese   p 
    (chr) (chr)  (dbl) 
1 Evan Gouda 0.6666667 
2 John Havarti 0.4000000 

我有興趣看到Pandas中的相似事物會是怎樣的。這是我想出了:

import io 
import pandas as pd 

x = pd.read_csv(io.StringIO(''' 
Idx Name Cheese1 Cheese2 Cheese3 
0 Evan Gouda  NaN  NaN 
1 John Cheddar Havarti Blue 
2 Evan Cheddar Gouda  NaN 
3 John Havarti Swiss  NaN'''), delim_whitespace=True) 

tidy = pd.melt(x, ['Idx', 'Name'], value_name='Cheese').dropna() 
tidy = tidy.groupby(['Name', 'Cheese']).size().reset_index(name='n') 
tidy['p'] = tidy.groupby('Name')['n'].transform(lambda n: n/sum(n)) 
tidy[tidy['p'] == tidy.groupby('Name')['p'].transform('max')].drop('n', 1) 

,輸出:

Name Cheese   p 
1 Evan Gouda 0.666667 
4 John Havarti 0.400000 

絕對不是那樣乾淨R,但也許有人更熟悉的熊貓可以如何改善這種權衡。