我有一个关于pandas数据帧操作的问题
假设我有两个不同大小的数据帧(它们具有相同的行数,但没有相同的列大小
a =pd.DataFrame({"code1":['A','B','C','D'],"code2":['E','F','G','H']})
b= pd.DataFrame({"code1":['A1','B','C','D'],"code2":['E','F','G','N'],"code3":['A2','L','M','']})
可视化:
a: code1 code2
0 A E
1 B F
2 C G
3 D H
b: code1 code2 code3
0 A1 E A2
1 B F L
2 C G M
3 D N
我的理想输出是有一个数据帧'c'表示:
c: addedword deletedword
0 A1,A2 A
1 L
2 M
3 N H
基本上,我想将'a'中的每一行与'b'中的相应行进行比较。然后比较每个元素,以便在添加字符串或删除的字符串时,显示到新的数据帧。
答案 0 :(得分:5)
使用设置差异
g = lambda x: map(set, x.values) # converts 2-D array to sets
f = lambda t: (t[1] - t[0], t[0] - t[1]) # t will be a tuple of sets
h = lambda y: map(','.join, y) # stitch sets back together
pd.DataFrame(
list(map(h, map(f, zip(*map(g, (a, b)))))),
columns=['Added', 'Deleted']
)
Added Deleted
0 A1,A2 A
1 L
2 M
3 ,N H
答案 1 :(得分:3)
使用np.in1d
pd.DataFrame({'addedword':[b.values[i][~np.in1d(b.values[i] ,a.values[i])] for i in range(len(a))],'deletedword':[a.values[i][~np.in1d(a.values[i] ,b.values[i])] for i in range(len(a))]})
Out[176]:
addedword deletedword
0 [A1, A2] [A]
1 [L] []
2 [M] []
3 [N, ] [H]
答案 2 :(得分:0)
通过简单的步骤使用set
,apply
和map
:
为两个数据框创建一组每行:
aset = a.apply(set, axis=1)
print(aset)
bset = b.apply(set, axis=1)
print(bset)
输出:
0 {A, E}
1 {F, B}
2 {C, G}
3 {H, D}
dtype: object
0 {E, A1, A2}
1 {F, L, B}
2 {C, M, G}
3 {, D, N}
dtype: object
创建上述集合之间的联接差异列表:
deletedword = pd.Series(map(lambda x: ",".join(x), aset - bset))
print(deletedword)
addedword = pd.Series(map(lambda x: ",".join(x), bset - aset))
print(addedword)
输出:
0 A
1
2
3 H
dtype: object
0 A1,A2
1 L
2 M
3 ,N
dtype: object
最后,从这些列表中创建一个数据框:
outdf = pd.DataFrame({"addedword":addedword, "deletedword":deletedword})
print(outdf)
输出:
addedword deletedword
0 A2,A1 A
1 L
2 M
3 ,N H