迭代 group_by 函数以删除重复数据

iterating group_by functions to deduplicate data

我正在尝试对数据进行重复数据删除,并通过迭代对每个分组行执行操作。

我 group_by 每个标签字段使用 pandas groupby 函数,然后我将每个标签字段转换为列。每个标签的值基于令牌字段,通过在“|”上拆分字符串。 我能够成功完成,但大型数据帧的性能非常慢。

迭代 for 循环中的每个分组行执行 200 it/s,这不会随着大数据扩展。那么有没有什么办法可以更快呢。

我试过按值遍历组,但速度很慢,我也尝试使用 np.vectorize,但我发现它本质上是循环遍历数据。

Eg Following is a dummy data
    categories = ["DEF,NAME,ADD"]
    id  text    label   tokens           id  text   DEF         NAME        ADD
    1   "abc"   DEF     X1 | X2     =>   1   "abc"  [X1,X2]     [Y1,Y2]     [Z1,Z2]
    1   "abc"   NAME    Y1 | Y2          2   "xyz"  [P1, P2]    [M1, M2]    []
    1   "abc"   ADD     Z1 | Z2
    2   "xyz"   DEF     P1 | P2
    2   "xyz"   NAME     M1 | M2
"Code for deduplicating and mapping to columns"
def deduplicate_data(
        df: pd.DataFrame,
        categories: List[str],
        category_column: str,
        token_column: str
)-> pd.DataFrame:

        new_columns = list(categories)
        new_columns.insert(0, "text")
        new_columns.insert(0, "id")
        acc = []
        new_dataset_length = len(df.groupby("id","text"))
        for (item_id, div_text), rows_idx in tqdm(df.groupby([
            "id",
            "text",
        ]).groups.items(), total=new_dataset_length):
            rows = df.loc[set(rows_idx.tolist())]  # selecting the grouped rows
            rows = categories_to_list(rows, categories, category_column, token_column)
            rows.insert(0, div_text)
            rows.insert(0, item_id)
            acc.append(rows)
        dataset = pd.DataFrame(acc, columns=new_columns)
        return dataset

Categories_to_list 函数将标签的选定标记转换为列表。为了简单起见,我只添加了主要功能。

迭代 for 循环中的每个分组行执行 200 it/s,这不会随着大数据扩展。那么有没有什么办法可以更快呢。

我希望它能更快地执行。

已编辑: 它可能包含具有 {ID、文本和标签} 的索引的重复条目。

    categories = ["DEF,NAME,ADD"]
    id  text    label   tokens           id  text   DEF         NAME        ADD
    1   "abc"   DEF     X1 | X2     =>   1   "abc"  [X1,X2]     [Y1,Y2]     [Z1,Z2]
    1   "abc"   NAME    Y1 | Y2          2   "xyz" [P1, P2, M1, M2]    []
    1   "abc"   ADD     Z1 | Z2
    2   "xyz"   DEF     P1 | P2
    2   "xyz"   DEF     M1 | M2

### EDIT 2
Need to make sure output return [] and not None values for newly mapped fields.

据我了解,您可以将 tokens 列拆分为 |,然后是 set_indexunstack():

final=(df.assign(tokens=df.tokens.str.split('|'))
   .set_index(['id','text','label']).unstack())
print(final)

              tokens                        
label            ADD         DEF        NAME
id text                                     
1  "abc"  [Z1 ,  Z2]  [X1 ,  X2]  [Y1 ,  Y2]
2  "xyz"         NaN  [P1 ,  P2]  [M1 ,  M2]

编辑后,使用:

final=  ((df.assign(tokens=df.tokens.str.split('|')).groupby(['id','text','label']).tokens
.apply(lambda x: [*itertools.chain.from_iterable(x)]).unstack().reset_index()))
print(final)

label  id   text         ADD                   DEF        NAME

0       1  "abc"  [Z1 ,  Z2]            [X1 ,  X2]  [Y1 ,  Y2]
1       2  "xyz"         NaN  [P1 ,  P2, M1 ,  M2]         NaN