计算数据框不同列中值的频率

时间:2019-02-11 20:06:45

标签: python pandas

我的数据具有以下形状:

id   column1   column2
a    x         1
a    x         3
a    y         3
b    y         1
b    y         2

我想获得每个ID的最多重复值及其频率百分比。

id   column1  %     column2  %
a    x        66.6  3        66.6
b    y        100.0 N/A      N/A

一种特殊情况是,当频率相等时,我会同时输出列和百分比的N / A。

现在,我的解决方案仅使用python字典和列表。但是,我正努力从DataFrame的角度来解决这个问题

4 个答案:

答案 0 :(得分:4)

我只能想到for循环然后concat

g=df.groupby('id')
pd.concat([ g[x].value_counts(normalize=True).groupby(level=0).head(1).to_frame('%').reset_index(level=1) for x in df.columns[1:]],axis=1)
Out[135]: 
   column1         %  column2         %
id                                     
a        x  0.666667        3  0.666667
b        y  1.000000        1  0.500000

答案 1 :(得分:3)

(非常)类似于@Wen的解决方案,但说明了一组比率相同的情况,结果应为char *insertCharact(char *source, char carac, size_t position) { size_t i, len; char *temp; len = source ? strlen(source) : 0; temp = (char *)malloc(len + 2); if (temp != NULL) { /* sanitize position */ if (position > len) position = len; /* copy initial portion */ for (i = 0; i < position; i++) { temp[i] = source[i]; } /* insert new character */ temp[i] = carac; /* copy remainder of the source string if any */ for (; i < len; i++) { temp[i + 1] = source[i]; } /* set the null terminator */ temp[i + 1] = '\0'; free(source); } return temp; }

NaN

u = df.groupby('id')
c = ('column1', 'column2')

def helper(group, col):
    return (group[col].value_counts(normalize=True, sort=True)
            .drop_duplicates(keep=False)
            .groupby(level=0).head(1)
            .to_frame(f'{col}_%')
            .reset_index(level=1))

pd.concat([helper(u, col) for col in c], axis=1)

答案 2 :(得分:2)

为了它的价值...
这对我来说更自然:

s = pd.Series(
    Counter([
        (i, c, v) for (i, c), v in df.set_index('id').stack().items()
    ])
)

d = s.groupby(level=[0, 1]).pipe(lambda g: [*zip(g.idxmax(), g.max() / g.sum())])

a = {}

for ((i, col, var), val) in d:
  a[(i, col, 'var')] = var
  a[(i, col, 'val')] = val

pd.Series(a).unstack([1, 2])

    column1       column2    
        val var       val var
a  0.666667   x  0.666667   3
b         1   y       0.5   1

答案 3 :(得分:0)

使用apply

import pandas as pd
from collections import Counter
df=pd.DataFrame({'id':['a','a','a','b','b'],'column1':['x','x','y','y','y'],'column2':[1,3,3,1,2]})


def get_max(row):
    tem_dict=Counter(row)
    return(tem_dict.most_common()[0][0], float(tem_dict.most_common()[0][1])/sum(tem_dict.values()))

pd.concat([pd.DataFrame(df.groupby('id')['column1'].apply(get_max).tolist(),columns=['Column1','%']),
           pd.DataFrame(df.groupby('id')['column2'].apply(get_max).tolist(),columns=['Column2','%'])],axis=1)