【问题标题】:Element wise comparison between two dataframes (one of them containing lists)两个数据帧之间的元素比较(其中一个包含列表)
【发布时间】:2017-09-10 00:26:08
【问题描述】:

我有两个两个数据框,一个由列表组成。

    in [00]: table01
    out[00]: 
       a  b
    0  1  2
    1  2  3

    in [01]: table02
    out[01]: 
          a     b
    0   [2]   [3]
    1 [1,2] [1,2]

现在我想比较两张表。如果table01中的元素也在table02的相同位置列表中,则返回True,否则返回False。所以我想要的表是:

          a     b
    0 False False  
    1  True False

我已尝试 table01 in table02 但收到错误消息:“DataFrame”对象是可变的,因此无法对它们进行哈希处理。

请与我分享此问题的正确解决方案。非常感谢!

【问题讨论】:

  • table01 in table02 没有太多尝试......
  • 好吧,纯粹的价值比较。 table01 == table02 有效,但我不明白为什么它在我的情况下不起作用。实际上,我发现如果我一个一个地调用单元格,使用“in”然后将结果放回去它可以工作。但是,我目前的解决方案非常耗时,这就是我问这个问题的原因。对不起,我的陈述不清楚。
  • 因为== 运算符被重载以处理数据帧。进行了元素明智的比较,并且由于 int != list,一切都是 False。 in 不适用于数据帧。

标签: python list pandas dataframe comparison


【解决方案1】:

使用setsdf.applymap

df3 = df1.applymap(lambda x: {x})
df4 = df2.applymap(set)

df3 & df4    
     a   b
0   {}  {}
1  {2}  {}

(df3 & df4).astype(bool)    
       a      b
0  False  False
1   True  False

user3847943's solution 是一个不错的选择,但可以使用set 成员资格测试来改进。

def find_in_array(a, b):
    return a in b

for c in df2.columns:
    df2[c] = df2[c].map(set)

vfunc = np.vectorize(find_in_array)

df = pd.DataFrame(vfunc(df1, df2), index=df1.index, columns=df1.columns)
df

       a      b
0  False  False
1   True  False

【讨论】:

  • 嗨,如果你有时间,我有一个问题...df1.apply(lambda x : x.values in df2.loc[x.index,x.name].values),为什么这不起作用...
  • @Wen df2.loc[...] 返回一个列表项,而一个列表项没有 .values。这是第一个问题。第二个是x.values是一个列表,在python中你不能真正做到list1 in list2,它不起作用。
  • 谢谢,好像不行..当我做df1.apply(lambda x :df2.loc[x.index,x.name])它返回df2,这让我觉得可以用这种方式解决问题
  • @Wen 是啊...df.apply 行为怪异...我基于它打开了一个新问题:stackoverflow.com/questions/46137355/…
  • 嗨,我知道了,通过使用 x.index 和 x.name 的想法,并更新了 ~ :)
【解决方案2】:

您可以使用 numpy.vectorize 轻松完成此操作。示例代码如下。

import numpy as np 
import pandas as pd 

t1 = pd.DataFrame([[1, 2],[2,3]])
t2 = pd.DataFrame([[[2],[3]],[[1,2],[1,2]]])

def find_in_array(a, b):
    return a in b

vfunc = np.vectorize(find_in_array)

print(vfunc(t1, t2))

【讨论】:

    【解决方案3】:

    试试这个

    df=pd.melt(df1.reset_index(),'index')
    df['v2']=pd.melt(df2.reset_index(),'index').value
    pd.melt(df2.reset_index(),'index')
    df['BOOL']=df.apply(lambda x: True if x.value in x.v2 else False, axis = 1)
    df.pivot('index','variable','BOOL')
    
    Out[491]: 
    variable      a      b
    index                 
    0         False  False
    1          True  False
    

    最后:

    df1.apply(lambda x: [(x==df2.loc[y,x.name])[y] for y in x.index])
    Out[668]: 
           a      b
    0  False  False
    1   True  False
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2018-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多