当列包含`List`而不是`Tuple`时,熊猫比较运算符`==`无法按预期工作
Posted
技术标签:
【中文标题】当列包含`List`而不是`Tuple`时,熊猫比较运算符`==`无法按预期工作【英文标题】:pandas comparision operator `==` not working as expected when column contain `List` instead `Tuple` 【发布时间】:2020-07-29 17:18:05 【问题描述】:import pandas as pd
import numpy as np
df = pd.DataFrame('Li':[[1,2],[5,6],[8,9]],'Tu':[(1,2),(5,6),(8,9)]
df
Li Tu
0 [1, 2] (1, 2)
1 [5, 6] (5, 6)
2 [8, 9] (8, 9)
Tuple
工作正常
df.Tu == (1,2)
0 True
1 False
2 False
Name: Tu, dtype: bool
当它的List
它给出值错误
df.Li == [1,2]
ValueError:长度必须匹配才能比较
【问题讨论】:
【参考方案1】:问题是list
s是不可哈希的,所以需要比较tuple
s:
print (df.Li.map(tuple) == (1,2))
0 True
1 False
2 False
Name: Li, dtype: bool
或者在列表理解中:
mask = [tuple(x) == (1,2) for x in df.Li]
#alternative
mask = [x == [1,2] for x in df.Li]
print (mask)
[True, False, False]
如果所有列表的长度相同:
mask = (np.array(df.Li.tolist()) == [1,2]).all(axis=1)
print (mask)
[ True False False]
【讨论】:
知道了。我只是想知道为什么list
不起作用。这也适用于我df.Li.apply(lambda x:(x==[1,2]))
【参考方案2】:
问题在于,pandas 将 [1, 2]
视为 series-like 对象,并尝试将 df.Li
的每个元素与 [1, 2]
的每个元素进行比较,因此出现错误:
ValueError:长度必须匹配才能比较
您无法将大小为 2 的列表与大小为 3 (df.Li
) 的列表进行比较。为了验证这一点,您可以执行以下操作:
print(df.Li == [1, 2, 3])
输出
0 False
1 False
2 False
Name: Li, dtype: bool
它不会抛出任何错误并且可以正常工作,但会按预期返回False
。为了使用列表进行比较,您可以执行以下操作:
# this creates an array where each element is [1, 2]
data = np.empty(3, dtype=np.object)
data[:] = [[1, 2] for _ in range(3)]
print(df.Li == data)
输出
0 True
1 False
2 False
Name: Li, dtype: bool
总而言之,这似乎是熊猫方面的一个错误。
【讨论】:
“所以这里将Tuple
视为标量,List
视为序列”对吗?
@anonymous 是的,我相信。【参考方案3】:
我的列 'vectors' 包含 numpy ndarrays,当我想与另一个 ndarray 'centroid' 进行比较时,我得到了同样的错误。以下适用于 numpy ndarrays:
df['vectors'].apply(lambda x: ((vec==centroid).sum() == centroid.shape[0]))
这也适用于列表:
df.Li.apply(lambda x: x==[1,2])
【讨论】:
以上是关于当列包含`List`而不是`Tuple`时,熊猫比较运算符`==`无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
scala 中是不是有一些 unzip 的扩展版本适用于任何 List[n-tuple] 而不仅仅是像 Unzip 这样的 List[pairs]?