猿问

如何通过从内容相似的多个 .csv 文件导入数据来创建数据框?

几个小时以来,我一直在为这个问题而苦苦挣扎,但我似乎无法弄清楚。如果有任何帮助,我将不胜感激。

背景

我正在尝试通过 python 为我在学校的研究实验室自动化数据操作。从实验中,.csv将生成一个包含 41 行数据(不包括标题)的文件,如下所示。

有时,同一实验的多次运行会产生.csv具有相同标头的文件,需要对它们取平均值以确保准确性。类似这样的行数和标题数相同的东西:

http://img4.mukewang.com/643e05df0001c6b304390153.jpg

到目前为止,我能够过滤基本名称以仅包含.csv具有相同参数的文件并将它们添加到数据框中。但是,我的问题是我不知道如何继续获得平均值。


我当前的代码和输出


代码:


import pandas as pd

import os


dir = "/Users/luke/Desktop/testfolder"


files = os.listdir(dir)

files_of_interests = {}


for filename in files:

    if filename[-4:] == '.csv':

        key = filename[:-5]

        files_of_interests.setdefault(key, [])

        files_of_interests[key].append(filename)


print(files_of_interests)


for key in files_of_interests:

    stack_df = pd.DataFrame()

    print(stack_df)

    for filename in files_of_interests[key]:

        stack_df = stack_df.append(pd.read_csv(os.path.join(dir, filename)))

    print(stack_df)

输出:


Empty DataFrame

Columns: []

Index: []

    Unnamed: 0  Wavelength       S2c  Wavelength.1        S2

0            0        1100  0.000342          1100  0.000304

1            1        1110  0.000452          1110  0.000410

2            2        1120  0.000468          1120  0.000430

3            3        1130  0.000330          1130  0.000306

4            4        1140  0.000345          1140  0.000323

[164 rows x 5 columns]

在这里提问!

所以我的问题是,如何让它分别为每个S2cand向右追加S2

解释:

对于具有相同标头名称的多个 .csv 文件,当我将其附加到列表时,它只是不断堆叠到前一个文件的底部,.csv这导致了[164 rows x 5 columns]上一节的 。我最初的想法是创建一个新的数据框,并且只从这些文件中的每一个附加S2c和,这样它就不会将它们堆叠在一起,而是将它们作为新列继续附加到右侧。之后,我可以进行某种形式的 pandas 列操作,将它们相加并除以运行次数(这只是文件数,因此在第二个FOR 循环下)。S2.csvlen(files_of_interests[key])

我试过的

  1. 我尝试创建一个空数据框并添加一个从np.arange(1100,1500,10)使用pd.DataFrame.from_records(). 并按照我在上一节中描述的那样将S2cand附加S2到数据框。发生了同样的问题,除此之外,它还产生了一堆 Nan 值,即使在进一步搜索之后我也没有足够的能力来处理这些值。

  2. 我已经阅读了此处发布的其他多个问题,许多人建议使用,pd.concat但由于答案是针对不同情况量身定制的,我无法真正复制它,也无法理解它的文档,所以我停止了这条路。

预先感谢您的帮助!

附加信息

我在代码中使用 macOS 和 ATOM。

可以在此处找到 csv 文件!

github: https://github.com/teoyi/PROJECT-Automate-Research-Process


函数式编程
浏览 132回答 3
3回答

九州编程

IIUC 你有:一堆 csv 文件,每个文件包含同一个实验的结果第一个相关列始终包含从 0 到 40 的数字(因此每个文件有 41 行)Wavelenght 和 Wavelength.1 列始终包含从 1100 到 1500 的相同值,增量为 10但在第一个相关列之前可能存在其他列第一列在 csv 文件中没有名称,直到第一个相关的名称以'Unnamed: '并且您想获得相同波长值的 S2 和 S2c 列的平均值。groupby这可以简单地用and完成mean,但我们首先必须过滤掉所有不需要的列。可以通过 的index_colandusecols参数来实现read_csv:...print(files_of_interests)# first concat the datasets:dfs = [pd.read_csv(os.path.join(dir, filename), index_col=1,                   usecols=lambda x: not x.startswith('Unnamed: '))       for key in files_of_interests for filename in files_of_interests[key]]df = pd.concat(dfs).reset_index()# then take the averagesdf = df.groupby(['Wavelength', 'Wavelength.1']).mean().reset_index()# reorder columns and add 1 to the index to have it to run from 1 to 41df = df.reindex(columns=['Wavelength', 'S2c', 'Wavelength.1', 'S2'])df.index += 1如果结果 df 中仍然有不需要的列,这个神奇的命令将有助于识别具有奇怪结构的原始文件:import pprintpprint.pprint([df.columns for df in files])使用 github testfolder 中的文件,它给出:[Index(['Unnamed: 0', 'Wavelength', 'S2c', 'Wavelength.1', 'S2'], dtype='object'), Index(['Unnamed: 0', 'Wavelength', 'S2c', 'Wavelength.1', 'S2'], dtype='object'), Index(['Unnamed: 0', 'Wavelength', 'S2c', 'Wavelength.1', 'S2'], dtype='object'), Index(['Unnamed: 0', 'Wavelength', 'S2c', 'Wavelength.1', 'S2'], dtype='object'), Index(['Unnamed: 0', 'Unnamed: 0.1', 'Wavelength', 'S2c', 'Wavelength.1',       'S2'],      dtype='object'), Index(['Unnamed: 0', 'Wavelength', 'S2c', 'Wavelength.1', 'S2'], dtype='object')]它明确表示第五个文件作为附加列。

慕盖茨4494581

如果您有数据框列表,例如:import pandas as pddata = {'col_1': [3, 2, 1, 0], 'col_2': [3, 1, 2, 0]}dflist = [pd.DataFrame.from_dict(data) for _ in range(5)]你可以做:pd.concat(dflist,axis=1)这看起来像:如果要在每个列名后附加一个数字,表明df它们来自哪个列,在 之前concat,请执行以下操作:for index, df in enumerate(dflist):     df.columns = [col+'_'+str(index) for col in df.columns]然后pd.concat(dflist,axis=1),结果:虽然我无法重现您的文件系统并确认它是否有效,但要从您的文件创建以上内容dflist,类似这样的方法应该有效:dflist = []for key in files_of_interests:    print(stack_df)    for filename in files_of_interests[key]:        dflist.append( pd.read_csv(os.path.join(dir, filename)) )

拉丁的传说

想要的是:键值对中每个文件的相应 S2c 和 S2 列将合并到一个.csv文件中以供进一步操作。删除冗余列以仅显示范围从 1100 到 1500 的单个列,Wavelength增量为 10。这需要使用pd.concat@zabop 和 @SergeBallesta 介绍的 which 如下所示:for key in files_of_interests:    list = []    for filename in files_of_interests[key]:        list.append(pd.read_csv(os.path.join(dir,filename)))        df = pd.concat(list, axis = 1)        df = df.drop(['Unnamed: 0', 'Wavelength.1'], axis = 1)        print(df)        df.to_csv(os.path.join(dir + '/', f"{filename[:-5]}_master.csv"))我必须使用files_of_interests[key]它才能读取文件名并且必须pd.read_csv读取正确的路径。除此之外,我添加axis = 1到pd.concatwhich 允许它与 for 循环一起水平连接以正确访问文件名。(我已经仔细检查了这些值,它们确实与相应的文件匹配.csv。)输出.csv看起来像这样:
随时随地看视频慕课网APP

相关分类

Python
我要回答