2017-10-21 95 views
1

假设我有一个熊猫数据帧,其中两列由字符串列表的如下所示一到在大熊猫数据帧串的两个列表之间的一对一映射

df=pd.DataFrame({'A' : [ ['a','b','c'], ['d','e','f'] ], 'B':[ ['g','h','i'], ['j','k','l'] ] }) 

我想连接在所述第一字符串元素在A中的第一个列表中的第一个字符串元素位于B的第一个列表中,并带有连字符等。最终的产品将是另一个C柱使

df['C'] = [ ['a-g','b-h','c-i'], ['d-j','e-k','f-l' ] ] 

我尝试了不同的功能与应用。()和map(),但什么也没有产生预期的结果,任何帮助表示赞赏。

回答

1

我会跟apply + np.core.defchararray.add做到这一点:

from numpy.core.defchararray import add 

df['C'] = df[['A', 'B']].apply(lambda x: add(add(x.A, '-'), x.B).tolist(), 1) 
df 

      A   B    C 
0 [a, b, c] [g, h, i] [a-g, b-h, c-i] 
1 [d, e, f] [j, k, l] [d-j, e-k, f-l] 

只记得我说过在列表中存储的数据。


如果有可能你的列是不是同样大小,你可以做一个if检查:

def foo(x): 
    if len(x.A) == len(x.B): 
     return add(add(x.A, '-'), x.B).tolist() 
    return [] 

df['C'] = df[['A', 'B']].apply(foo, 1) 
+0

它不工作!实际上,它给出了与前面建议的答案相同的错误'传递值的形状是(17,2),指数意味着(17,34)'知道数据框的形状是17行和34列。我尽可能地回答了你的答案,它在数据框仅包含这2列的时候工作,当你添加其他类型的额外列时,它就不再工作了。我试图用df [['A','B']]替换df.apply。现在应用它给我下面的错误'无法从形状(15)广播输入数组到形状(2)' –

+0

@MartinHeusen如果你如果要连接所有34列,最好确保每个单元格的元素数量完全相同。 –

+0

不,我不想连接34列,只有2列,我知道每行中列表的长度是相同的。每行的长度可能不同,但在每行中它们是相同的! –

2

您可以使用str.cat

df['C'] = df.A.str.cat(df.B, sep='-') 

df 
# A B C 
#0 a e a-e 
#1 b f b-f 
#2 c g c-g 
#3 d h d-h 

或者直接加入两列:在编辑的数据

df.A + '-' + df.B 

#0 a-e 
#1 b-f 
#2 c-g 
#3 d-h 
#dtype: object 

更新

df=pd.DataFrame({'A':[['a','b','c'], ['d','e','f']], 'B':[['g','h','i'], ['j','k','l']]}) 

df['C'] = df.apply(lambda r: [a+'-'+b for a,b in zip(r.A, r.B)], axis=1) 

df 
#   A   B     C 
#0 [a, b, c] [g, h, i] [a-g, b-h, c-i] 
#1 [d, e, f] [j, k, l] [d-j, e-k, f-l] 
+0

@MartinHeusen您可以编辑您的问题详细说说吗? –

+0

感谢您的回答。其实我在提问时犯了一个错误。我要连接的两列都是由列表组成的,所以数据框如下所示:df = pd.DataFrame({'A':[['a','b','c'],['d', 'e','f']],'B':[['g','h','i'],['j','k','l']]})是df ['C'] = [['a-g','b-h','c-i'],['d-j','e-k','fl']],你能请帮助? –

+0

尝试'df ['C'] = df.apply(lambda r:[a +' - '+ b for a,b in zip(r.A,r.B)],axis = 1)''。 – Psidom

1

选项1
使用numpy.core.defchararray.add

from numpy.core.defchararray import add 

a = np.array(df.values.tolist()) 

df.assign(C=add(add(a[:, 0], '-'), a[:, 1]).tolist()) 

      A   B    C 
0 [a, b, c] [g, h, i] [a-g, b-h, c-i] 
1 [d, e, f] [j, k, l] [d-j, e-k, f-l] 

选项2
list自定义子类有趣的方式,并重新定义+

class list_(list): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 

    def __add__(self, other): 
     return list_(map('-'.join, (map(str, t) for t in zip(self, other)))) 

df.assign(C=df.applymap(list_).sum(1).apply(list)) 

      A   B    C 
0 [a, b, c] [g, h, i] [a-g, b-h, c-i] 
1 [d, e, f] [j, k, l] [d-j, e-k, f-l] 
相关问题