首页 > 解决方案 > 计算数据框单元格中的非重复数据 - 熊猫

问题描述

我有一个数据框:

import pandas as pd
data = {'userName': {0: 'john', 1: 'amanda', 2: 'sara', 3: 'john'}, 'serialNum': {0: '[a4G, bweQ, fp_dE4]', 1:'' , 2: '[H2dw45, IfC4, bAf23g, Lkfr54-op, a3dLa]', 3: '[Tr45b, kM30, a4G, riU91]'}}
df = pd.DataFrame(data)
df

*每个用户名都是唯一的。对于每个用户名,我想计算 serialNum 列中的数据数。

我的代码是:

df['serialNum'] = df['serialNum'].str.strip('[]').str.replace("'", "").str.replace('"', '').replace('', np.nan).str.split(',').fillna({i: [] for i in df.index})



df_count = (df['serialNum'].str.len()
                .groupby(df['userName'], sort=False).sum()
     ).to_frame(name='count').reset_index()

我的 df_count 数据框:

用户名 序列号
约翰 7
阿曼达 0
萨拉 5

但我不想为每个用户名计算重复数据(serialNum),真正的 df_count 是:

用户名 序列号
约翰 6
阿曼达 0
萨拉 5

我的问题是:如何计算没有重复数据(在列 serialNum 中)?

如果您对计算 serialNum 列中的值数量有更好的报价,请与我分享。

注意:我更喜欢使用 pandas 或 numpy 方法和函数,而不是编写新函数或for loop

标签: pandasdataframenumpy

解决方案


使用explode+ :groupby agg nunique

u_count_df = (
    df.explode('serialNum')
        .groupby('userName', sort=False).agg({'serialNum': 'nunique'})
        .reset_index()
        .rename(columns={'serialNum': 'uCount'})
)

u_count_df

  userName  uCount
0     john       6
1   amanda       0
2     sara       5

使用当前设置,由于字符串的处理方式,您需要去掉多余的空格:

e = df.explode('serialNum')
e['serialNum'] = e['serialNum'].str.strip()

u_count_df = (
    e.groupby('userName').agg({'serialNum': 'nunique'})
        .reset_index()
        .rename(columns={'serialNum': 'uCount'})
)

或者改变字符串的分割方式:

df['serialNum'] = (
    df['serialNum'].str.strip('[]')
        .replace({"'": '', '"': ''}, regex=True)
        .replace({'': np.NaN})
        .str.split(r'\s*,\s*')
        .fillna({i: [] for i in df.index})
)

u_count_df = (
    df.explode('serialNum')
        .groupby('userName', sort=False).agg({'serialNum': 'nunique'})
        .reset_index()
        .rename(columns={'serialNum': 'uCount'})
)

u_count_df

  userName  uCount
0     john       6
1   amanda       0
2     sara       5

推荐阅读