【问题标题】:How to show multiple matches in the same row separated by comma in Pandas Dataframe?如何在 Pandas Dataframe 中以逗号分隔的同一行中显示多个匹配项?
【发布时间】:2021-09-20 15:36:08
【问题描述】:

在与我的查找值相同的行显示任何匹配值时遇到问题,即

我的第一张桌子:

some_primary_key
unique_value_1
unique_value_2
unique_value_3

其他表:

some_primary_key values
unique_value_1 some_value_1
unique_value_1 some_value_2
unique_value_2 some_value_3
unique_value_2 some_value_4
unique_value_3 some_value_5
unique_value_3 some_value_6

最后我想要这个:

some_primary_key values
unique_value_1 some_value_1, some_value_2
unique_value_2 some_value_3, some_value_4
unique_value_3 some_value_5, some_value_6

我应该使用列表推导迭代 df 项目并创建匹配值列表的列表吗?有什么想法吗?

答案:

这是我的示例解决方案:

import pandas as pd

data = {'some_primary_key':['unique_value_1',
                            'unique_value_2',
                            'unique_value_3']*2,
        'values':['some_value_1', 'some_value_3', 'some_value_5',
                  'some_value_2', 'some_value_4', 'some_value_6']
                      }
                                                                          
df = pd.DataFrame(data=data)


list_of_values = []
for item in df['some_primary_key']:
    filtered_values = df[df['some_primary_key']==item]
    list_of_values.append(','.join(x for x in filtered_values['values']))

df['values'] = list_of_values
df = df.drop_duplicates()
print(df)

还有其他简洁的解决方案吗? :)

【问题讨论】:

  • 嗨@qrzep,我只是用基准更新我的答案。看看那个。 :)

标签: python python-3.x pandas dataframe numpy


【解决方案1】:

您正在寻找的是groupby。在将 transform 分组到 some_primary_key 之后,您可以应用任何自定义函数。

你可以试试这个:

concat_func  = lambda x: ','.join(map(str, x.sort_values(ascending=True).unique()))
df['values'] = df.groupby(['some_primary_key'])['values'].transform(concat_func)

然后,df 将为每个some_primary_key 连接values,这使得values 重复。因此,只需删除重复的行:

df = df.drop_duplicates()

输出:

  some_primary_key                     values
0   unique_value_1  some_value_1,some_value_2
1   unique_value_2  some_value_3,some_value_4
2   unique_value_3  some_value_5,some_value_6

PS:

concat_funcsort_values()unique() 中应用了更好的视图并防止同一行出现相同的values。否则,如果df 是:

  some_primary_key        values
0   unique_value_1  some_value_1
1   unique_value_1  some_value_1

输出将是:

  some_primary_key                     values
0   unique_value_1  some_value_1,some_value_1

如果这是所需的输出,只需使用以下concat_func

concat_func = lambda x: ','.join(map(str, x))

【讨论】:

    【解决方案2】:

    具有基准的可能替代方案:

    import pandas as pd
    
    data = {
        'some_primary_key':['unique_value_1', 'unique_value_2', 'unique_value_3'] * 2,
        'values':['some_value_1', 'some_value_3', 'some_value_5', 'some_value_2', 'some_value_4', 'some_value_6']
    }
    
    def func_1(df):
      return df.groupby(['some_primary_key'])['values'].apply(lambda x: ', '.join(x)).reset_index()
    
    def func_2(df):
      return df.groupby(['some_primary_key'])['values'].apply(', '.join).reset_index()
    
    def func_3(df):
      return df.groupby('some_primary_key')['values'].apply(', '.join)
    
    def func_4(df):
      return df.groupby('some_primary_key')['values'].agg(', '.join)
    
    def func_5(df):
      return df.groupby(['some_primary_key'], as_index = False).agg({'values': ', '.join})
    
    def func_6(df):
      return df.groupby('some_primary_key').agg({'values': ', '.join}).reset_index()
    
    def func_7(df):
      concat_func  = lambda x: ','.join(map(str, x.sort_values(ascending=True).unique()))
      df['values'] = df.groupby(['some_primary_key'])['values'].transform(concat_func)
      return df.drop_duplicates()
                                                                          
    df = pd.DataFrame(data=data)
    
    print('func_1(df) runtime: ', end="")
    %timeit func_1(df)
    
    # OR
    
    print('func_2(df) runtime: ', end="")
    %timeit func_2(df)
    
    # OR
    
    print('func_3(df) runtime: ', end="")
    %timeit func_3(df)
    
    # OR
    
    print('func_4(df) runtime: ', end="")
    %timeit func_4(df)
    
    # OR
    
    print('func_5(df) runtime: ', end="")
    %timeit func_5(df)
    
    # OR
    
    print('func_6(df) runtime: ', end="")
    %timeit func_6(df)
    
    # OR
    
    print('func_7(df) runtime: ', end="")
    %timeit func_7(df)
    
    

    输出:

      some_primary_key                     values
    0   unique_value_1  some_value_1, some_value_2
    1   unique_value_2  some_value_3, some_value_4
    2   unique_value_3  some_value_5, some_value_6
    

    基准输出:

    func_1(df) runtime: 100 loops, best of 5: 1.95 ms per loop
    func_2(df) runtime: 100 loops, best of 5: 2.11 ms per loop
    func_3(df) runtime: 1000 loops, best of 5: 1.01 ms per loop
    func_4(df) runtime: 1000 loops, best of 5: 1.18 ms per loop
    func_5(df) runtime: 100 loops, best of 5: 2.86 ms per loop
    func_6(df) runtime: 100 loops, best of 5: 2.46 ms per loop
    func_7(df) runtime: 100 loops, best of 5: 5.01 ms per loop
    

    【讨论】:

    • 太棒了!我认为值得一提的是,第 3 次和第 4 次返回 pd.series - others 返回 df。
    • 好建议。我会补充一点。如果你喜欢我的回答,请点个赞。 :)
    • 我是新手,所以我没有足够的声誉:(但当我得到我的代表点时我一定会给你一个赞成票:)
    • 欢迎来到 SO。 :)
    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多