Python 3.x 跨列的唯一值(按行排列)缺少值

Python 3.x 跨列的唯一值(按行排列)缺少值,python-3.x,pandas,unique,Python 3.x,Pandas,Unique,我有一个像 import pandas as pd import numpy as np df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'], "Col2": ['A', 'B', 'B', 'A', 'C'], "Col3": ['A', 'B', 'C', 'A', 'C']}) 我希望获得每行的跨

我有一个像

import pandas as pd
import numpy as np

df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
                  "Col2": ['A', 'B', 'B', 'A', 'C'],
                  "Col3": ['A', 'B', 'C', 'A', 'C']})
我希望获得每行的跨列的唯一组合,并使用这些值创建一个新列,排除缺少的值

我现在要做的代码是

def handle_missing(s):
    
    return np.unique(s[s.notnull()])
    
def unique_across_rows(data):
    
    
    unique_vals = data.apply(handle_missing, axis = 1)
    
    # numpy unique sorts the values automatically
    merged_vals = unique_vals.apply(lambda x: x[0] if len(x) == 1 else '_'.join(x))
    
    return merged_vals

df['Combos'] = unique_across_rows(df)
这将返回预期的输出:

       Col1    Col2  Col3   Combos
  0       A       A     A       A
  1     NaN       B     B       B
  2       B       B     C       B_C
  3       B       A     A       A_B
  4       C       C     C       C
在我看来,熊猫内部应该有一种更为矢量化的方法来实现这一点:我如何才能做到这一点?

试试(下面的解释)

输出:

  Col1 Col2 Col3 Combos
0    A    A    A      A
1  NaN    B    B      B
2    B    B    C    B_C
3    B    A    A    A_B
4    C    C    C      C

您还可以在轴=1上使用
agg/apply
,如下所示:

df['Combos'] = df.agg(lambda x: '_'.join(sorted(x.dropna().unique())),axis=1)


您可以尝试一种简单的列表理解方法,对于较大的数据帧可能更有效:

df['combos'] = ['_'.join(sorted(k for k in set(v) if pd.notnull(k))) for v in df.values]
或者,您可以将上述列表理解包装在一个更可读的函数中:

def combos():
    for v in df.values:
        unique = set(filter(pd.notnull, v))
        yield '_'.join(sorted(unique))

df['combos'] = list(combos())


用字符串占位符“-”填充nan。从col1、col2、col3列表中创建一个唯一的数组,并删除占位符。将唯一数组值与“-”连接起来

import pandas as pd
import numpy as np

def unique(list1): 
   if '-' in list1:
       list1.remove('-')
   x = np.array(list1) 
   return (np.unique(x))

df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
              "Col2": ['A', 'B', 'B', 'A', 'C'],
              "Col3": ['A', 'B', 'C', 'A', 'C']}).fillna('-')

 s="-"
 for key,row in df.iterrows():
     df.loc[key,'combos']=s.join(unique([row.Col1, row.Col2, row.Col3])) 

 print(df.head())

在一些较大的数据帧上,列表理解被证明是最快的方法,生成器函数也没有慢多少。
def combos():
    for v in df.values:
        unique = set(filter(pd.notnull, v))
        yield '_'.join(sorted(unique))

df['combos'] = list(combos())
  Col1 Col2 Col3 combos
0    A    A    A      A
1  NaN    B    B      B
2    B    B    C    B_C
3    B    A    A    A_B
4    C    C    C      C
import pandas as pd
import numpy as np

def unique(list1): 
   if '-' in list1:
       list1.remove('-')
   x = np.array(list1) 
   return (np.unique(x))

df = pd.DataFrame({"Col1": ['A', np.nan, 'B', 'B', 'C'],
              "Col2": ['A', 'B', 'B', 'A', 'C'],
              "Col3": ['A', 'B', 'C', 'A', 'C']}).fillna('-')

 s="-"
 for key,row in df.iterrows():
     df.loc[key,'combos']=s.join(unique([row.Col1, row.Col2, row.Col3])) 

 print(df.head())