2016-02-02 101 views
1

我对计算大熊猫分类列浓度的旧函数有问题。似乎已经发生了一些变化,无法对分类系列的方法的结果进行子集分组。计算大熊猫分类的“浓度”

最小非工作例如:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({"A":["a","b","c","a"]}) 

def get_concentration(df,cat): 
    tmp = df[cat].astype("category") 
    counts = tmp.value_counts() 
    obs = len(tmp) 
    all_cons = [] 
    for key in counts.keys(): 
     single = np.square(np.divide(float(counts[key]),float(obs))) 
     all_cons.append(single) 
     return np.sum(all_cons) 

get_concentration(df, "A") 

这导致counts["a"]一个关键的错误。我很确定这在熊猫的过去版本中起作用,并且文档似乎没有提及关于.value_counts()方法的更改。

+0

我补充说,也不需要''categorical'一个dtype'简化和矢量版本。 – Stefan

+0

在其他问题中,return语句应该在for循环之外。 – Alexander

回答

1

既然你在一个循环中迭代(而不是以矢量方式工作),你可能只是明确地迭代对。它简化了语法,恕我直言:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({"A":["a","b","c","a"]}) 

def get_concentration(df,cat): 
    tmp = df[cat].astype("category") 
    counts = tmp.value_counts() 
    obs = len(tmp) 
    all_cons = [] 
    # See change in following line - you're anyway iterating 
    # over key-value pairs; why not do so explicitly? 
    for k, v in counts.to_dict().items(): 
     single = np.square(np.divide(float(v),float(obs))) 
     all_cons.append(single) 
     return np.sum(all_cons) 

>>> get_concentration(df, "A") 
0.25 
+0

这似乎是最自然的解决方案!谢谢:) – Matthias

+0

@Matthias你非常欢迎。但是,我建议您将数字代码中的循环看作“红旗”。 –

1

要修复当前功能,只需使用.ix(参见下文)访问index值。你可能会更好地使用向量化函数 - 我最后加了一个。

df = pd.DataFrame({"A":["a","b","c","a"]}) 

tmp = df[cat].astype('category') 
counts = tmp.value_counts() 
obs = len(tmp) 
all_cons = [] 
for key in counts.index: 
    single = np.square(np.divide(float(counts.ix[key]), float(obs))) 
    all_cons.append(single) 
    return np.sum(all_cons) 

产量:

get_concentration(df, "A") 

0.25 

你可能想尝试向量化版本,这也并不一定需要categorydtype,如:

def get_concentration(df, cat): 
    counts = df[cat].value_counts() 
    return counts.div(len(counts)).pow(2).sum() 
2

让我们在方法论同意:

>>> df.A.value_counts() 
a 2 
b 1 
c 1 

obs = len((df['A'].astype('category')) 
>>> obs 
4 

浓度应为(每Herfindahl Index)如下:

>>> (2/4.) ** 2 + (1/4.) ** 2 + (1/4.) ** 2 
0.375 

即相当于(熊猫0.17+):

>>> ((df.A.value_counts()/df.A.count()) ** 2).sum() 
0.375 

如果你真的想要一个功能:

def concentration(df, col): 
    return ((df[col].value_counts()/df[col].count()) ** 2).sum() 

>>> concentration(df, 'A') 
0.375