【问题标题】:Reading file from directory based on the selected filename on the list根据列表中选定的文件名从目录中读取文件
【发布时间】:2020-08-16 10:15:01
【问题描述】:

我有大量二维文件,我从中计算 XX 参数,如下所示。

 '2019-10-12_17-43.csv',
 '2019-10-12_17-42.csv',
 '2019-10-12_17-41.csv',
 '2019-10-12_17-44.csv',
 '2019-10-12_17-40.csv',
 '2019-10-11_17-40.csv',
 ......................
 and so on...

我能够创建一个文件名列表并计算该特定文件的 XX 参数。在随后的计算之后,我创建了一个名为 YY 的数据框,其中包含参数以及包含从中计算它的文件名的列。在计算出的 XX 参数的特定值的基础上,我想绘制所有产生它的二维数据。我还从数据框的列中创建了一个文件名列表。显然代码更长到 XX 参数计算,但是为了从列表中选定的文件名中读取数据,我在最后一个块中使用以下代码:

# arbitrary functions
def Aval (a, b):
   ..............

def Bval (a, b):
   ..............

file_path = r"C:\Users\Desktop\Data"
read_files = glob.glob(os.path.join(file_path,"*.csv"))

# generating the list of filenames

file_list = []
XYZ_array = []
ABC_array = []

for (root, dirs, files) in os.walk(file_path):
   for filenames in files:
       file_list.append(filenames)
       df= pd.read_csv(os.path.join(root, filenames), header=0)

       #Calculation from the files
       ABC = ..................
       XYZ = ..................
       ABC_array.append(ABC)
       XYZ_array.append(XYZ)


#creating a dataframe from the arrays        
newdf = pd.DataFrame ({'ABC': ABC_array, 'XYZ':XYZ_array, 'Filename':file_list }) 

生成的数据框如下所示:

Timestamp          ABC        XYZ           Filename  

2019-10-11_07-52   1.934985   0.187962     2019-10-11_07-52.csv 
2019-10-11_07-53   1.926435   0.200828     2019-10-11_07-53.csv  
2019-10-11_07-54   1.922927   0.215204     2019-10-11_07-54.csv
2019-10-11_07-55   1.951818   0.216678     2019-10-11_07-55.csv
2019-10-11_07-56   1.922523   0.245144     2019-10-11_07-56.csv
...                ...        ...          ...                    
2019-10-13_18-21   2.028409   1.149067     2019-10-13_18-21.csv
2019-10-13_18-22   2.027896   1.015862     2019-10-13_18-22.csv
2019-10-13_18-23   2.013004   0.871320     2019-10-13_18-23.csv
2019-10-13_18-24   1.991576   0.755164     2019-10-13_18-24.csv
2019-10-13_18-25   1.908259   0.570786     2019-10-13_18-25.csv

ABC 值被分成三个 bin 垃圾箱 = [1.76,1.86,1.96]

Abc_sorted = newdf.sort_values('ABC')
Abc_sorted['Bin_names'] = pd.cut(Abc_sorted['ABC'], bins, labels=['1.76','1.86','1.96'])
T_df = Abc_sorted.sort_values(by=['Bin names']).dropna()

产生如下数据框:

Timestamp            ABC          XYZ       Filename              Bin_names
2019-10-12_17-43    1.769676    72.841836   2019-10-12_17-43.csv    1.76
2019-10-12_17-42    1.771429    74.583635   2019-10-12_17-42.csv    1.76
2019-10-12_17-41    1.774526    76.104981   2019-10-12_17-41.csv    1.76
2019-10-12_17-44    1.774678    68.314091   2019-10-12_17-44.csv    1.76
2019-10-12_17-40    1.779273    76.589191   2019-10-12_17-40.csv    1.76
... ... ... ... ... ... ... ... ... ...
2019-10-12_09-48    1.988249    85.279987   2019-10-12_09-48.csv    1.96
2019-10-13_09-04    1.988266    28.716690   2019-10-13_09-04.csv    1.96
2019-10-12_11-27    1.988597    76.978562   2019-10-12_11-27.csv    1.96
2019-10-11_16-19    1.985438    76.343396   2019-10-11_16-19.csv    1.96
2019-10-11_08-11    1.999933    0.251199    2019-10-11_08-11.csv    1.96

基于 bin_name 1.76 和文件名创建一个新的数据框,并创建一个包含文件名的列表:

ndf = T_df.loc[Total_df.Bin_names =='1.76'][['Filename', 'Bin_names']]
filename_list=ndf['Filename'].tolist()

这导致数据框为:

Filename             Bin_names
2019-10-12_17-43.csv    1.76
2019-10-12_17-42.csv    1.76
2019-10-12_17-41.csv    1.76
2019-10-12_17-44.csv    1.76
2019-10-12_17-40.csv    1.76

现在的主要任务是从主目录导入filename_list中的文件:

for i in range(len(filename_list)):
        print (filename_list[i])
for file in read_files:
    if fnmatch.fnmatch(file, filename_list[i]):
        print(file)

其中read_files 是路径,file 是路径中的文件名,filename_list 是包含多个文件的列表。我已将数据分箱为 3 个不同的值,我只想导入 ABC 参数值为 1.76 的文件。但这似乎不起作用,并且没有返回任何内容。有人可以帮忙吗?

【问题讨论】:

  • 什么是i?没有返回任何内容,因为您只是在打印。可能需要更多信息。请阅读minimal reproducible example,编写一个minimal 玩具示例来复制问题。
  • @wwii 问题现在更新为更清晰的文本和代表性代码。提前致谢
  • 大概ndf = T_df.loc... 是给你带来麻烦的那行,但是没有人能说出来,因为我们不知道newdf 中的内容,我们也不知道T_df 的样子或如何您正在合并数据。 minimal reproducible example 的目的是为我们提供重现问题所需的一切,包括代表性数据 - 重点是 minimal(用于代码和数据) - 有时为你的问题做一个 mre 会在你得到答案之前为你突出问题。
  • 可以肯定地说newdf 可以用import numpy as np; import pandas as pd; import random,string; abc = np.random.default_rng().normal(1.5, .5, 1000); xyz = np.random.default_rng().normal(1.5, .5, 1000); fnames = [''.join(random.choices(string.ascii_letters,k=7)) for _ in range(1000)]; newdf = pd.DataFrame ({'ABC': abc, 'XYZ':xyz, 'Filename':fnames}) 制作/模仿吗?如果是这样,请将其包含在您的问题中(因为我们没有任何这些 csv 文件,所有这些东西都是无关紧要的)。
  • 那么我们肯定需要知道您是如何制作分配给 newdf['Bin names'] 的系列的 - 这似乎是您的问题不可或缺的一部分,但您只是跳过了。

标签: python list file csv fnmatch


【解决方案1】:

如果ndf 看起来像这样:

>>> ndf
               Filename  Bin_names
0  2019-10-12_17-43.csv       1.76
1  2019-10-12_17-42.csv       1.76
2  2019-10-12_17-41.csv       1.76
3  2019-10-12_17-44.csv       1.76
4  2019-10-12_17-40.csv       1.76

filename_list 看起来像这样:

>>> filename_list = ndf['Filename'].to_list()
>>> filename_list
['2019-10-12_17-43.csv', '2019-10-12_17-42.csv', '2019-10-12_17-41.csv', '2019-10-12_17-44.csv', '2019-10-12_17-40.csv']

文件位于

file_path = r"C:\Users\Desktop\Data"

那么你所有文件的完整路径应该是

>>> [os.path.join(file_path, name) for name in filename_list]
['C:\\Users\\Desktop\\Data\\2019-10-12_17-43.csv', 'C:\\Users\\Desktop\\Data\\2019-10-12_17-42.csv', 'C:\\Users\\Desktop\\Data\\2019-10-12_17-41.csv', 'C:\\Users\\Desktop\\Data\\2019-10-12_17-44.csv', 'C:\\Users\\Desktop\\Data\\2019-10-12_17-40.csv']
>>> 

您还可以将文件路径添加到Filename

>>> ndf.Filename.apply(lambda x: os.path.join(file_path,x))
0    C:\Users\Desktop\Data\2019-10-12_17-43.csv
1    C:\Users\Desktop\Data\2019-10-12_17-42.csv
2    C:\Users\Desktop\Data\2019-10-12_17-41.csv
3    C:\Users\Desktop\Data\2019-10-12_17-44.csv
4    C:\Users\Desktop\Data\2019-10-12_17-40.csv
Name: Filename, dtype: object
>>>

或使用pathlib

>>> import pathlib
>>> p = pathlib.PurePath(file_path)
>>> ndf.Filename.apply(p.joinpath)
0    C:\Users\Desktop\Data\2019-10-12_17-43.csv
1    C:\Users\Desktop\Data\2019-10-12_17-42.csv
2    C:\Users\Desktop\Data\2019-10-12_17-41.csv
3    C:\Users\Desktop\Data\2019-10-12_17-44.csv
4    C:\Users\Desktop\Data\2019-10-12_17-40.csv
Name: Filename, dtype: object
>>>

您使用os.walk 查找所有文件,然后将文件名附加到列表中,但必须使用os.path.join(root, filenames) 使用pandas 打开文件。也许文件位于不同的目录中,您应该在创建 file_list 时保存整个路径 - 这样您就可以使用它们的 absolute 路径访问这些文件,而无需搜索它们。

【讨论】:

  • 感谢您的帮助。导入所选文件的最后一段仍然不显示任何内容。我在这里错过了什么吗?
  • still displays nothing - 我不知道那是什么意思。见编辑。
  • 假设我想从整个文件列表中读取 ndf 数据框中列出的文件的内容并进行计算。最后一段应该是那部分,但这不起作用。第二个for loop 无法正常运行,因为当此段运行时,除了从ndf 数据框创建的filename_list 中的文件名之外,什么都没有显示。根据您之前的建议,我在filename_list 中添加了文件的路径。因此,您在编辑中提到的内容应该包含在此范围内。
猜你喜欢
  • 2015-09-20
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多