Python 如何使用CSV中的列附加目录中的所有文件?
我有一个有10000张图片的目录。它们被标记为1.png、2.png等。我有一个CSV文件,其中包含10000个标签,如frog、truck等。如何循环所有文件以从CSV添加标签?1.png变为“frog.1.png”,假设frog是csv中的标签1 以下是我迄今为止所尝试的:Python 如何使用CSV中的列附加目录中的所有文件?,python,loops,csv,directory,Python,Loops,Csv,Directory,我有一个有10000张图片的目录。它们被标记为1.png、2.png等。我有一个CSV文件,其中包含10000个标签,如frog、truck等。如何循环所有文件以从CSV添加标签?1.png变为“frog.1.png”,假设frog是csv中的标签1 以下是我迄今为止所尝试的: import os, sys, fileinput import pandas as pd #read csv labels labels = pd.read_csv('trainLabels.csv',sep=',',
import os, sys, fileinput
import pandas as pd
#read csv labels
labels = pd.read_csv('trainLabels.csv',sep=',',header=0,usecols=[1])
#sort files in directory numerically
fnames = sorted([fname for fname in os.listdir(data_dir)
if fname.endswith('.png')], key=lambda f: int(f.rsplit(os.path.extsep, 1)
[0].rsplit(None,1)[-1]))
#Now that order of labels and files match, rename all files using common counter, i
i = 0
for fname in os.listdir(data_dir):
os.rename(fnames[i],labels[i]+'.'+fnames[i])
i = i+1
os.rename不适用于series,我很难找到一个能够适应不同数据类型的约定。从外观上看,您的labels变量是不可订阅的,这意味着您不能以您现在的方式调用其中一个元素 从熊猫文档: pd.read_csv返回一个数据帧或文本解析器,而不是我认为您期望的行列表 您不需要“需要”熊猫来阅读csv:
labels = open('trainLabels.csv','r').read().split('\n')
[labels[i]=labels[i].split(',')[0] for i in range(len(labels))]
#increment 0 above to whatever the column index you want is, this will return the first column
print(labels) #just to check it looks the way you want it to
当然,这是一个额外的行,不可读,但您得到了您想要的数据结构为演示做了一些准备:
$ for f in `echo "1 2 3 4 10"`; do touch "${f}.png"; done
$ echo "a,b,c,d,e" > names.csv
$ ls
1.png 2.png 3.png 4.png 10.png names.csv
我有1,2,3,4,10
(而不是5
)来演示排序,而不是创建10个文件。它将与任何数量的文件完全相同
在Python中,在同一目录中运行:
>>> import os
>>> import csv
>>> with open('names.csv', 'r') as file:
... reader = csv.reader(file)
... labels = reader.next() # reader is a regular iterator, you can also iterate row by row.
>>> labels
['a', 'b', 'c', 'd', 'e']
>>> fnames = [fname for fname in os.listdir('.') if fname.endswith('.png')]
['1.png', '10.png', '2.png', '3.png', '4.png'] # Because string '10.png' comes earlier than '2.png'
>>> fnames = sorted(fnames, key = lambda f: int(os.path.splitext(f)[0])) # If fnames contain full paths you will need to modify this
>>> fnames
['1.png', '2.png', '3.png', '4.png', '10.png'] # Now we have correct numerical order
>>> len(labels) == len(fnames) # For consistency should check this. Depends on your requirements.
True
>>> for label, fname in zip(labels, fnames):
... os.rename(fname, label + '_' + fname)
结果:
$ ls
a_1.png b_2.png c_3.png d_4.png e_10.png names.csv
注:
- 如果使用不同的csv阅读器,只需确保
标签
变量包含所需的名称,而不是某个对象或迭代器。我使用了来自的csv阅读器
- 如果你有更复杂的文件名结构(不是
),你的生活会更艰难,需要更多的代码来排序。如果您想让它更简单,只需用前导零填充所有数字,例如,对于.png
文件,文件名将是10000
,00001.png
等等。操作系统应该自动为您排序00002.png
os.rename
不适用于series”。不确定这是什么意思。对不起,我得到的错误类型是:TypeError:“NoneType”对象不是subscriptableWhich值是None
?