寻找不等长列表之间的最小可能差异

时间:2019-01-09 16:23:35

标签: python pandas list

我有一个数据框,其中包含两列AB,其中包含列表:

import pandas as pd

df = pd.DataFrame({"A" : [[1,5,10],  [], [2], [1,2]],
                   "B" : [[15, 2],   [], [6], []]})

我想构造第三列C,该列的定义应等于AB中的列表元素之间的最小可能差值(如果它们不是空的) ,如果其中一个或两个为空,则为0。

第一行的最小差异为1(我们取绝对值..),第二行由于列表为空而为0,第三行为4,第四行又由于一个空列表而为0,所以我们最终以:

df["C"] = [1, 0, 4, 0]

5 个答案:

答案 0 :(得分:3)

这是不容易矢量化的,因为您有object个dtype系列列表。您可以对itertools.product使用列表推导:

from itertools import product

zipper = zip(df['A'], df['B'])
df['C'] = [min((abs(x - y) for x, y in product(*vals)), default=0) for vals in zipper]

# alternative:
# df['C'] = [min((abs(x - y) for x, y in product(*vals)), default=0) \
#            for vals in df[['A', 'B']].values]

print(df)
#             A        B  C
# 0  [1, 5, 10]  [15, 2]  1
# 1          []       []  0
# 2         [2]      [6]  4
# 3      [1, 2]       []  0

答案 1 :(得分:2)

您可以使用以下列表推导,检查两列中笛卡尔积(itertools.product)的min差异

[min(abs(i-j) for i,j in product(*a)) if all(a) else 0 for a in df.values]
[1, 0, 4, 0]

答案 2 :(得分:2)

df['C'] = df.apply(lambda row: min([abs(x - y) for x in row['A'] for y in row['B']], default=0), axis=1)

答案 3 :(得分:1)

我只想再次介绍unnesting

df['Diff']=unnesting(df[['B']],['B']).join(unnesting(df[['A']],['A'])).eval('C=B-A').C.abs().min(level=0)
df.Diff=df.Diff.fillna(0).astype(int)
df
Out[60]: 
            A        B  Diff
0  [1, 5, 10]  [15, 2]     1
1          []       []     0
2         [2]      [6]     4
3      [1, 2]       []     0

仅供参考

def unnesting(df, explode):
    idx=df.index.repeat(df[explode[0]].str.len())
    df1=pd.concat([pd.DataFrame({x:np.concatenate(df[x].values)} )for x in explode],axis=1)
    df1.index=idx
    return df1.join(df.drop(explode,1),how='left')

答案 4 :(得分:0)

我认为这可行

def diff(a,b):    
    if len(a) > 0 and len(b) > 0:
        return min([abs(i-j) for i in a for j in b])
    return 0

df['C'] = df.apply(lambda x: diff(x.A, x.B), axis=1)
df

           A        B   C
0   [1, 5, 10]  [15, 2] 1
1           []       [] 0
2          [2]      [6] 4
3       [1, 2]       [] 0