计算,比较和汇总熊猫数据框

时间:2019-03-22 17:57:35

标签: python pandas

我的数据如下:

ID  my_val db_val
a       X       X
a       X       X
a       Y       X
b       X       Y
b       Y       Y
b       Y       Y
c       Z       X
c       X       X
c       Z       X

预期结果:

ID  my_val  db          match
 a  X:2;Y:1  X     full_match
 b  Y:2;X:1  Y     full_match
 c  z:2;X:1  X  partial_match

full_match是db_val与最丰富的my_val匹配时 当db_val在其他值中但与顶部值不匹配时,partial_match是。

我目前的方法是按ID分组,然后将值计数到一个单独的列中,然后将值及其计数串联在一起,然后将每个ID的所有值汇总到一行中。

这是我汇总列的方式:

def all_hits_aggregate_df(df, columns=['my_val']):
    grouped = data.groupby('ID')
    l=[]
    for c in columns:
        res = grouped[c].value_counts(ascending=False, normalize=False).to_frame('count_'+c).reset_index(level=1)
        res[c] = res[c].astype(str) +':'+ res['count_'+c].astype(str)
        l.append(res.groupby('ID').agg(lambda x: ';'.join(x)))
    return reduce(lambda x, y: pd.merge(x, y, on = 'ID'), l)

在比较阶段,我遍历每一行并将my_val列解析为列表,然后进行比较。

我确定比较步骤的效率极低,但是我不确定在聚合之前如何进行此操作,以避免稍后在过程中解析生成的字符串。

2 个答案:

答案 0 :(得分:2)

我们可以按ID groupby来使用DataFrame,然后使用my_val来计数value_counts的值,并使用to_json转换为json,这在格式上进行了一些小的更改后,我们要求的格式(我们只需要删除大括号和引号,并用分号替换逗号)。在分组的数据上,我们还取first的{​​{1}}(大概是每个ID的唯一值)并计算匹配百分比(超过50%的匹配项将得出{{1 }},0-50%是db_val,0%是full_match):

partial_match

输出:

no_match

答案 1 :(得分:0)

这应该为您提供所需的第一部分:

df['equal'] = df.my_val == df.db_val

df2 = pd.DataFrame()
df2['my_val'] = df.groupby('ID')['my_val'].sum()
df2['db'] = df.groupby('ID')['db_val'].unique()

df2['match_val'] = df.groupby('ID')['equal'].sum()
df2['match'] = ''
df2.loc[df2.match_val/len(df2.my_val) > 0.5, 'match'] = 'full_match'
df2.loc[df2.match_val/len(df2.my_val) <= 0.5, 'match'] = 'partial_match'
df2.loc[df2.match_val/len(df2.my_val) == 0, 'match'] = 'no_match'
df2 = df2.drop(columns = 'match_val')

print(df2)
   my_val   db          match
ID                           
a     XXY  [X]     full_match
b     XYY  [Y]     full_match
c     ZXZ  [X]  partial_match