为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

函数式编程 2023-04-18 10:51:41
几个小时以来,我一直在为这个问题而苦苦挣扎,但我似乎无法弄清楚。如果有任何帮助,我将不胜感激。背景我正在尝试通过 python 为我在学校的研究实验室自动化数据操作。从实验中,.csv将生成一个包含 41 行数据(不包括标题)的文件,如下所示。有时,同一实验的多次运行会产生.csv具有相同标头的文件,需要对它们取平均值以确保准确性。类似这样的行数和标题数相同的东西:到目前为止,我能够过滤基本名称以仅包含.csv具有相同参数的文件并将它们添加到数据框中。但是,我的问题是我不知道如何继续获得平均值。我当前的代码和输出代码:import pandas as pdimport osdir = "/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 DataFrameColumns: []Index: []    Unnamed: 0  Wavelength       S2c  Wavelength.1        S20            0        1100  0.000342          1100  0.0003041            1        1110  0.000452          1110  0.0004102            2        1120  0.000468          1120  0.0004303            3        1130  0.000330          1130  0.0003064            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])我试过的我尝试创建一个空数据框并添加一个从np.arange(1100,1500,10)使用pd.DataFrame.from_records(). 并按照我在上一节中描述的那样将S2cand附加S2到数据框。发生了同样的问题,除此之外,它还产生了一堆 Nan 值,即使在进一步搜索之后我也没有足够的能力来处理这些值。我已经阅读了此处发布的其他多个问题,许多人建议使用,pd.concat但由于答案是针对不同情况量身定制的,我无法真正复制它,也无法理解它的文档,所以我停止了这条路。预先感谢您的帮助!附加信息我在代码中使用 macOS 和 ATOM。可以在此处找到 csv 文件!github: https://github.com/teoyi/PROJECT-Automate-Research-Process
查看完整描述

3 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

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 averages

df = df.groupby(['Wavelength', 'Wavelength.1']).mean().reset_index()


# reorder columns and add 1 to the index to have it to run from 1 to 41

df = df.reindex(columns=['Wavelength', 'S2c', 'Wavelength.1', 'S2'])

df.index += 1

如果结果 df 中仍然有不需要的列,这个神奇的命令将有助于识别具有奇怪结构的原始文件:


import pprint


pprint.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')]

它明确表示第五个文件作为附加列。


查看完整回答
反对 回复 2023-04-18
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

如果您有数据框列表,例如:


import pandas as pd

data = {'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)

这看起来像:

//img1.sycdn.imooc.com//643e061a00010ec905610156.jpg

如果要在每个列名后附加一个数字,表明df它们来自哪个列,在 之前concat,请执行以下操作:

for index, df in enumerate(dflist):
    df.columns = [col+'_'+str(index) for col in df.columns]

然后pd.concat(dflist,axis=1),结果:

//img1.sycdn.imooc.com//643e062600013a1f06540147.jpg

虽然我无法重现您的文件系统并确认它是否有效,但要从您的文件创建以上内容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)) )


查看完整回答
反对 回复 2023-04-18
?
拉丁的传说

TA贡献1789条经验 获得超8个赞

想要的是:

  1. 键值对中每个文件的相应 S2c 和 S2 列将合并到一个.csv文件中以供进一步操作。

  2. 删除冗余列以仅显示范围从 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看起来像这样:

//img1.sycdn.imooc.com/643e064a000143f506600234.jpg


查看完整回答
反对 回复 2023-04-18
  • 3 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信