【问题标题】:Unique combination of two columns with mixed values具有混合值的两列的唯一组合
【发布时间】:2021-07-26 14:35:32
【问题描述】:

我有两列 col1 和 col2

我正在尝试创建键列以显示 abba

问题代码:

import pandas as pd
pd.DataFrame({'Col1':['a','c','b','e'],
              'Col2':['b','d','a','f']})

【问题讨论】:

    标签: python pandas combinations


    【解决方案1】:

    试试frozenset

    df['out'] = df.agg(frozenset,1).str.join(sep='')
    Out[220]: 
    0    ab
    1    dc
    2    ab
    3    ef
    dtype: object
    

    【讨论】:

    • 嗯,这给了我 1.3.0 的错误,TypeError: 'frozenset' type is unordered,但适用于 1.2.2
    • 它对我有用,但df.agg(frozenset, axis=1).apply(sorted).str.join('') 可能更适合排序,因为它给了我“ba”而不是“ab”
    • @ALollz 很有趣~让我找到发行说明看看会发生什么~
    【解决方案2】:

    使用 numpy 对字符串进行排序,然后加入/求和。无论值在列中出现的顺序如何,这都会创建一个唯一键。

    import numpy as np
    
    df['key'] = np.sort(df.to_numpy(), axis=1).sum(1)
    
    #  Col1 Col2 key
    #0    a    b  ab
    #1    c    d  cd
    #2    b    a  ab
    #3    e    f  ef
    

    如果您有兴趣,numpy.sort 是执行此操作的高效方式。任何 .agg.apply 都会减少行上的慢循环,因此随着 DataFrame 变大,它们的扩展性会更差。相对于numpy.sort,其他方法通常至少慢一个数量级。

    import perfplot
    import pandas as pd
    import numpy as np
    from string import ascii_lowercase
    
    
    def apply_sorted(df):
        return df.apply(sorted, 1).str.join(sep='')
    
    def numpy_sort(df):
        return pd.Series(np.sort(df.to_numpy(), axis=1).sum(1))
    
    
    perfplot.show(
        setup=lambda N: pd.DataFrame({'Col1': np.random.choice([*ascii_lowercase], N), 
                                      'Col2': np.random.choice([*ascii_lowercase], N)}),
        kernels=[
            lambda df: apply_sorted(df),
            lambda df: numpy_sort(df),
        ],
        labels=['apply_sorted', 'numpy_sort'],
        n_range=[2 ** k for k in range(25)],
        equality_check=lambda x,y: x.compare(y).empty,
        relative_to=1,
        xlabel='len(df)'
    )
    

    【讨论】:

    • 是的,numpy 排序确实有效。我尝试了一个涉及 apply lambda 的解决方案,它所花费的时间是frozenset 的一半。
    【解决方案3】:

    我会使用sorted 内置函数来完成这项任务

    import pandas as pd
    df = pd.DataFrame({'Col1':['a','c','b','e'],'Col2':['b','d','a','f']})
    df['key'] = df.apply(sorted,1).str.join(sep='')
    print(df)
    

    输出

      Col1 Col2 key
    0    a    b  ab
    1    c    d  cd
    2    b    a  ab
    3    e    f  ef
    

    解释:它确实按字典顺序对每一行进行排序,然后连接这些元素。假设:Col1 的每个元素都是单个字符,Col2 的每个元素都是单个字符。

    【讨论】:

      猜你喜欢
      • 2014-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      相关资源
      最近更新 更多