所以,我在Python中使用pandas。我正在读一个看起来像这样的csv:
imageName color1 color2 color3 color4
img1 Red Red Red Red
img2 Blue Green Red Blue
img3 Yellow Blue Red White
img4 Blue Blue Blue Blue
如果color1,color2,color3和color4都相等,我想要的是打印行(按图像名称)。 如果我在SQL中这样做
SELECT: imageName
FROM: rows
WHERE: color1 == color2 == color3 == color4
会给我img1和img4
我对Pandas很新,并且一直试图弄清楚语法,但我一直遇到问题。
我现在正在尝试的是:
if (df[(df['color1'] == df['color2'] == df['color3'] == df['color4']])]
print df['imageName']
但无论我尝试什么,我都会遇到错误。
我得到了:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any(), or a.all().
但我正在努力弄清楚在哪里使用它们。或者如果我甚至以正确的方式去做。提前谢谢!
答案 0 :(得分:2)
这是一种方法,我试图找出一个矢量化方法,基本上你定义了一个函数,它接受你的行然后调用apply,传递函数名和param axis=1
以逐行应用。 color_cols只是由color_cols = [col for col in df if 'color' in col]
In [21]:
def all_equal(x):
return x['color1'] == x['color2'] == x['color3'] == x['color4']
df[color_cols].apply(all_equal, axis=1)
Out[21]:
0 True
1 False
2 False
3 True
dtype: bool
In [23]:
df[df[color_cols].apply(all_equal, axis=1)]['imageName']
Out[23]:
0 img1
3 img4
Name: imageName, dtype: object
更快的方法是定义一个掩码并使用按位运算符:
In [27]:
# mask tests if color 1 equals color 2 and color 3 equals color 4 and color 1 equals color 3 if this is true then all must be the same value
mask = (df['color1'] == df['color2']) & (df['color3'] == df['color4']) & (df1['color1'] == df['color3'])
mask
Out[27]:
0 True
1 False
2 False
3 True
dtype: bool
In [28]:
df[mask]['imageName']
Out[28]:
0 img1
3 img4
Name: imageName, dtype: object
<强>计时强>
In [29]:
%timeit df.query("color1 == color2 == color3 == color4").imageName
100 loops, best of 3: 7.24 ms per loop
In [30]:
%timeit df[(df['color1'] == df['color2']) & (df['color3'] == df['color4']) & (df1['color1'] == df['color3'])].imageName
100 loops, best of 3: 3.22 ms per loop
另一种方法是调用eval
:
In [39]:
%timeit df[df.eval("color1 == color2 & color3 == color4 & color1 == color3")].imageName
100 loops, best of 3: 7.53 ms per loop
In [40]:
%timeit df[df[color_cols].apply(all_equal, axis=1)].imageName
100 loops, best of 3: 2.55 ms per loop
掩码方法比此样本数据集的查询和eval方法快2倍。 apply
方法实际上是最快的方法,但它不会像其他方法那样扩展,因为它实际上循环遍历每一行。
答案 1 :(得分:2)
您可以使用query
:获取类似语法:
>>> df.query("color1 == color2 == color3 == color4")
imageName color1 color2 color3 color4
0 img1 Red Red Red Red
3 img4 Blue Blue Blue Blue
>>> df.query("color1 == color2 == color3 == color4").imageName
0 img1
3 img4
Name: imageName, dtype: object
或者,您可以使用布尔系列索引:
>>> df[df.filter(like="color").apply(pd.Series.nunique, axis=1) == 1]
imageName color1 color2 color3 color4
0 img1 Red Red Red Red
3 img4 Blue Blue Blue Blue
虽然这略有不同,因为nunique
会忽略NaN
。