Python:使用 Pandas 在 csv 中打印具有匹配列内容的行名称

Python: Print row name in csv with matching column contents using Pandas

所以,我在 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

如果颜色 1、颜色 2、颜色 3 和颜色 4 都相等,我想要的是打印行(按图像名称)。 如果我在 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().

但我正在努力弄清楚在哪里使用它们。或者如果我什至以正确的方式去做。提前致谢!

这是一种方法,我试图找出一个矢量化方法,基本上你定义一个函数来获取你的行然后调用应用程序,传递函数名称和参数 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

掩码方法比此示例数据集的查询和评估方法快 2 倍以上。 apply 方法实际上是最快的方法,但它的扩展性不如其他方法,因为它本质上是在每一行上循环。

您可以使用 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