如何用彼此更简单的方法减去所有熊猫数据框元素?

时间:2019-03-01 08:02:30

标签: python pandas dataframe

假设我有一个这样的数据框

name time
a    10
b    30
c    11
d    13

现在我想要一个这样的新数据框


    name1 name2 time_diff
    a     a      0
    a     b     -20
    a     c     -1
    a     d     -3
    b     a      20
    b     b      0
    b     c      19
    b     d      17
    .....
    .....
    d     d      0

嵌套循环,可以使用lambda函数,但是当元素数量超过200个时,for循环会花费太多时间才能完成,或者我应该说,我总是必须中断该过程。有人知道熊猫查询方式还是更快更轻松的方法。我的数据框的形状是1600x2

3 个答案:

答案 0 :(得分:3)

首先在merge的帮助列中使用交叉联接,获得区别并仅选择必要的列:

df = df.assign(A=1)
df = pd.merge(df, df, on='A', suffixes=('1','2'))
df['time_diff'] = df['time1'] - df['time2']
df = df[['name1','name2','time_diff']]
print (df)
   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0

另一种在第一层和第二层使用MultiIndex.from_productreindex的解决方案:

df = df.set_index('name')
mux = pd.MultiIndex.from_product([df.index, df.index], names=['name1','name2'])

df = (df['time'].reindex(mux, level=0)
        .sub(df.reindex(mux, level=1)['time'])
        .rename('time_diff')
        .reset_index())

答案 1 :(得分:3)

使用itertools的解决方案:

import itertools
d=pd.DataFrame(list(itertools.product(df.name,df.name)),columns=['name1','name2'])
dic = dict(zip(df.name,df.time))
d['time_diff']=d.name1.map(dic)-d.name2.map(dic)
print(d)
   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0

答案 2 :(得分:1)

另一种方法是df.apply

df=pd.DataFrame({'col':['a','b','c','d'],'col1':[10,30,11,13]})
index = pd.MultiIndex.from_product([df['col'], df['col']], names = ["name1", "name2"])
res=pd.DataFrame(index = index).reset_index()
res['time_diff']=df.apply(lambda x: x['col1']-df['col1'],axis=1).values.flatten()

O / P:

   name1 name2  time_diff
0      a     a          0
1      a     b        -20
2      a     c         -1
3      a     d         -3
4      b     a         20
5      b     b          0
6      b     c         19
7      b     d         17
8      c     a          1
9      c     b        -19
10     c     c          0
11     c     d         -2
12     d     a          3
13     d     b        -17
14     d     c          2
15     d     d          0