代码之家  ›  专栏  ›  技术社区  ›  Raksha

基于另一列中的值替换数据帧列中的值

  •  2
  • Raksha  · 技术社区  · 6 年前

    尝试,我有:

    test = pd.DataFrame([[1,'A', 'B', 'A B r'], [0,'A', 'B', 'A A A'], [2,'B', 'C', 'B a c'], [1,'A', 'B', 's A B'], [1,'A', 'B', 'A'], [0,'B', 'C', 'x']])
    replace = [['x', 'y', 'z'], ['r', 's', 't'], ['a', 'b', 'c']]
    

    仅当最后一列中的部分值存在于 replace 在与该行第一列中的数字对应的位置列出。

    例如,查看前三行:

    enter image description here

    所以,既然“R”在 replace[1] ,该单元格变为 A B 0 . “A”不在 replace[0] ,所以它保持 A A A , “a”和“c”都在 replace[2] 所以它变成了 B 0 0 , 等。

    我试过类似的东西

    test[3] = test[3].apply(lambda x: ' '.join([n if n not in replace[test[0]] else 0 for n in test.split()]))
    

    但这并没有改变什么。

    3 回复  |  直到 6 年前
        1
  •  2
  •   jezrael    6 年前

    在集合中使用列表理解和查找:

    test[3] = [' '.join('0' if i in set(replace[a]) else i for i in b.split()) 
                         for a,b in zip(test[0], test[3])]
    print (test)
       0  1  2      3
    0  1  A  B  A B 0
    1  0  A  B  A A A
    2  2  B  C  B 0 0
    3  1  A  B  0 A B
    4  1  A  B      A
    5  0  B  C      0
    

    或转换为以前的设置以提高性能:

    r = [set(x) for x in replace]
    test[3]=[' '.join('0' if i in r[a] else i for i in b.split()) for a,b in zip(test[0], test[3])]
    
        2
  •  3
  •   rafaelc    6 年前

    IIUC,使用 zip 以及完成此任务的清单理解。

    我简化并创建了一个自定义 replace_ 功能,但可以随意使用 regex 必要时进行更换。

    def replace_(st, reps):
        for old,new in reps:
            st = st.replace(old,new)
        return st
    
    df['new'] = [replace_(b, zip(replace[a], ['0']*3)) for a,b in zip(df[0], df[3])]
    

    输出

        0   1   2   3       new
    0   1   A   B   A B r   A B 0
    1   0   A   B   A A A   A A A
    2   2   B   C   B a c   B 0 0
    3   1   A   B   s A B   0 A B
    4   1   A   B   A       A
    5   0   B   C   x       0
    
        3
  •  2
  •   BENY    6 年前

    我终于知道你需要什么了

    s=pd.Series(replace).reindex(test[0])
    
    [ "".join([dict.fromkeys(y,'0').get(c, c) for c in x]) for x,y in zip(test[3],s)]
    ['A B 0', 'A A A', 'B 0 0', '0 A B', 'A', '0']