我的数据具有以下形状:
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的角度来解决这个问题
答案 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)