从概念上讲,我有两个长度相等的列表,一个包含labels
,另一个包含data
。所以我问this question,没有意识到我真正拥有的是两个numpy
数组,而不是两个列表。
我所拥有的是包含cat_01.jpg
,cat_02.jpg
,dog_01.jpg
,dog_02.jpg
,dog_03.jpg
,fish_01.jpg
等图片的文件夹, ......,tiger_03.jpg
,zebra_01.jpg
和zebra_02.jpg
。我还有一个成功的程序来读取它们,将每个文件名的一部分解析为labels
数组,并将相应的图像数据解析为我的data
数组,这样我最终得到的结果如下:
>>> labels
array(['cat', 'cat', 'dog', ..., 'tiger', 'zebra', 'zebra' ])
>>> type( data )
<class 'numpy.ndarray'>
>>> data[0][0][0]
array([78, 88, 98])
这是有道理的 - 在每个sample
(column
,row
),data[ sample ][ row ][ column ]
表示(R,G,B)数据点。
我想指定一个搜索标签,例如'dog'
,并且(从概念上)使用它来生成两个&#34;子列表&#34; - 第一个包含labels
列表中的所有(相同)匹配标签,另一个包含来自data
的关联图像数据。但是我需要保留原始数据格式,而不是列表,在这种情况下numpy
数组(但如果有更通用的,数据不敏感的方法,我很乐意了解它)。我怎么能这样做?
更新:这里有一些特定的测试代码,用于重现我面临的情况,以及基于Stephen Rauch的解决方案草图:
import os, glob
from PIL import Image
import numpy as np
import pandas as pd # not critical to question
def load_image(file):
data = np.asarray(Image.open(file),dtype="float")
return data
MasterClass = ['cat','dog','fsh','grf','hrs','leo','owl','pig','tgr','zbr']
os.chdir('data\\animals')
filelist = glob.glob("*.jpg")
full_labels = np.array([MasterClass.index(os.path.basename(fname)[:3]) for fname in filelist])
full_images = np.array([load_image(fname) for fname in filelist])
# The following sketch a solution, but which leads to incompatible data types
# That is, the test_images differ from the full_images and/or so do the labels
# with regard to the data types involved.
df = pd.DataFrame(dict(label=list(full_labels),data=list(full_images)))
criteria = df['label'] == MasterClass.index('dog')
test_labels = np.array(df[criteria]['label'])
test_images = np.array(df[criteria]['data'])
两个注释:
tiger_03.jpg
,我正在消除对现实的迷惑。事实上,上面的代码需要像tgr03.jpg
这样的文件名,而我最终使用的标签列表甚至不是['cat', 'cat', 'dog', ...]
,而是MasterClass
列表中的索引列表 - 是,[0, 0, 1, ...]
问题是:如何让test_labels
和test_images
采用与原始full_labels
和full_images
相同的格式,但会基于选择{{1}像上面描绘的那个?这个代码目前并没有达到这种级别的数据兼容性 - 它没有实现严格的&#34;切片&#34;功能
答案 0 :(得分:1)
如果你可以使用熊猫,那么这种事情非常好。
如果您已有数据框,则可以执行以下操作:
# build a logical condition
have_dog = df['animal_label'] == 'dog'
# select the data when that condition is true
print(df[have_dog])
import pandas as pd
import numpy as np
animal_label = ['cat', 'cat', 'dog', 'dog', 'dog', 'fish', 'fish', 'giraffe']
data = [0.3, 0.1, 0.9, 0.5, 0.4, 0.3, 0.2, 0.8]
data = [np.array((x,) * 3) for x in data]
df = pd.DataFrame(dict(animal_label=animal_label, data=data))
print(df)
have_dog = df['animal_label'] == 'dog'
print(df[have_dog])
animal_label data
0 cat [0.3, 0.3, 0.3]
1 cat [0.1, 0.1, 0.1]
2 dog [0.9, 0.9, 0.9]
3 dog [0.5, 0.5, 0.5]
4 dog [0.4, 0.4, 0.4]
5 fish [0.3, 0.3, 0.3]
6 fish [0.2, 0.2, 0.2]
7 giraffe [0.8, 0.8, 0.8]
animal_label data
2 dog [0.9, 0.9, 0.9]
3 dog [0.5, 0.5, 0.5]
4 dog [0.4, 0.4, 0.4]
答案 1 :(得分:0)
如果我理解你的问题,可以通过这样切片来完成:
selector = 'fish'
matching_labels = labels[labels==selector]
matching_data = data[labels==selector]
或者,您可以使用上一个问题中答案的方法,并通过alist
alist = numpy.array(alist)
设为一个numpy数组
答案 2 :(得分:0)
基于Stephen Rauch's answer to my earlier simpler question,可以按如下方式解决此问题:
# assume full_labels and full_images exist as per test code in updated question
tuples = (x for x in zip(list(full_labels),list(full_images)) if x[0] == MasterClass.index('dog'))
xlabels,ximages = map(list, zip(*tuples))
test_labels = np.array(xlabels)
test_images = np.array(ximages)