2016-07-13 14 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」+ indexの形式です。もしJohnが翌日に4つのチーズを持っていたら、4番目の列を追加する必要があり、分析スクリプトはそれを処理できる必要があります。

答えて

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文を使って多少の修正を加えましたが、それはjankyです。 – 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 

私は見ることに興味があった同じようなことがパンダのようにどのように見えるか。 Rとして間違いなく

Name Cheese   p 
1 Evan Gouda 0.666667 
4 John Havarti 0.400000 

としてきれいではない、多分パンダとのより多くの知り合いの誰かがこれを改善する方法で重量を量ることができます:出力

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) 

:これは私が思いついたものです。

関連する問題