【问题标题】:New column in csv based on list, pythoncsv中基于列表的新列,python
【发布时间】:2018-04-20 13:50:45
【问题描述】:

我有一个 csv 文件 (VV_AL_3T3_P3.csv),每个 csv 文件的每一行都对应于浮游生物的 tiff 图像。它看起来像这样:

Particle_ID  Diameter  Image_File                   Lenght ....etc
          1     15.36  VV_AL_3T3_P3_R3_000001.tif    18.09
          2     17.39  VV_AL_3T3_P3_R3_000001.tif    19.86
          3     17.21  VV_AL_3T3_P3_R3_000001.tif    21.77
          4      9.42  VV_AL_3T3_P3_R3_000001.tif     9.83

图像全部放在一个文件夹中,然后在文件夹中按形状分类。 tiff 图像的名称由 Image_file + Particle ID 组成;例如第一行:VV_AL_3T3_P3_R3_000001_1.tiff

现在,我想使用 python 在我已经拥有的 csv 文件 (VV_AL_3T3_P3.csv) 中添加一个名为“Class”的新列,其中包含每个 .tiff 文件所在的文件夹(类)的名称;像这样:

Particle_ID  Diameter  Image_File                   Lenght   Class
          1     15.36  VV_AL_3T3_P3_R3_000001.tif    18.09   Spherical
          2     17.39  VV_AL_3T3_P3_R3_000001.tif    19.86   Elongated
          3     17.21  VV_AL_3T3_P3_R3_000001.tif    21.77   Pennates
          4      9.42  VV_AL_3T3_P3_R3_000001.tif     9.83   Others

到目前为止,我有一个包含每个 tiff 文件所在文件夹名称的列表。这是将成为新列的列表。但是,我该怎么做才能让每个文件夹都适合它的行呢?换句话说,将“类”与“粒子 ID”和“图像文件”进行匹配。

现在:

## Load modules:
import os
import pandas as pd
import numpy as np
import cv2

## Function to recursively list files in dir by extension
def file_match(path,extension):
    cfiles = []
    for root, dirs, files in os.walk('./'):
        for file in files:
            if file.endswith(extension):
                cfiles.append(os.path.join(root, file))
    return cfiles


## Load all image file at all folders:
image_files = file_match(path='./',extension='.tiff')

## List of directories where each image was found:
img_dir = [os.path.dirname(one_img)[2:] for one_img in image_files]
len(img_dir)

## List of images:
# Image file column in csv files:
img_file = [os.path.basename(one_img)[:22] for one_img in image_files]
len(img_file)
# Particle id column in csv files:
part_id  = [os.path.basename(one_img)[23:][:-5] for one_img in image_files]
len(part_id)

## I have the information related with the collage picture, particle id and the classification folder.
# Now i need to create a loop where this information is merged...

## Load csv file:
data = pd.read_csv('VV_AL_3T3.csv')
sample_file = data['Image File']  # Column name
sample_id   = data['Particle ID'] # Particle ID

我在这里看到过类似的案例:Create new column in dataframe with match values from other dataframe

但我真的不知道如何使用“map.set_index”,而且他有两个数据框,而我只有一个。

【问题讨论】:

    标签: python linux list csv


    【解决方案1】:

    对于问题的第一部分,请使用 os.path.split

    如果您的路径是... /home/usuario/Desktop/Classification/Fraction_9to20um/Classes/test

    os.path.split(path)[1]
    

    将返回测试。

    然后在你的 for 循环中,将其附加到每一行

    for row in rows:
        row = row.append(os.path.split(path)[1]
        writer.writerow(row)
    

    参考:https://docs.python.org/3/library/os.path.html

    【讨论】:

      【解决方案2】:

      您可以使用os.path.split(path) 将路径分成两部分:开始部分和最后部分,无论是文件还是目录。

      例如:

      myPath = '/test/second/third/theFile.txt'
      firstPair = os.path.split(myPath)
      # firstPair == ('/test/second/third', 'theFile.txt')
      

      如果您有完整的文件路径并且想要最后一个目录名,请运行此命令两次:

      filePath = '/home/usuario/Desktop/Classification/Fraction_9to20um/Classes/ClassA/img_001.tiff'
      firstPair = os.path.split(filePath)
      secondPair = os.path.split(firstPair[0])
      print(secondPair[1])
      # ClassA
      

      【讨论】:

      • 我按照您的指示进行操作,但是我有 827 个 .tiff 图像。有没有办法一次完成?
      【解决方案3】:

      听起来 my_files 是 (paths+tiff_file_name) 的列表。你想要的似乎是父目录绝对路径的最后一段。

      所以,/some/path/to/directory/classA/instance.tiff 将被分配给 classA

      有两种方法,两种解释略有不同

      1) 路径的倒数第二部分是类。

      rows = [file.split(os.path.sep)[-2] for file in my_files]

      2) 文件的包含目录,相对于Classes 目录,是类。

      rows = [ os.path.relpath( os.path.dirname(file), '/home/usuario/Desktop/Classification/Fraction_9to20um/Classes/' ) for file in my_files ]


      编辑(用于澄清/示例):为了写出类及其文件,

      with open(output_path, "w") as f:
          writer = csv.writer(f)
          # optionally, write the header
          writer.writerow(['full_img_path', 'img_class'])
          for file in my_files:
              img_class = os.path.relpath(
                  os.path.dirname(file),
                  '/home/usuario/Desktop/Classification/Fraction_9to20um/Classes/'
              )
              writer.writerow([file, img_class])
      

      您的问题不清楚您是否希望 output_path 成为 class.csv 或 VV_AL_3T3_P3.csv,但希望您看到它很容易互换。

      请注意,如果输入和输出之间存在一对一的对应关系(输入 -> 简单变换 -> 输出),则上述模式往往很容易实现/调试。但是,一旦您开始聚合数据(例如,每个类的平均文件数),您可能希望开始探索像 pandas 这样的数据操作库。

      【讨论】:

      • 你是对的,my_files 是 (paths+.tiff) 的列表。我遵循了第二种方法,现在我有一个名为 rows 的列表,其中包含不同的类,包含 .tiff 文件的文件夹的名称。但是,如何将其转换为我的 csv 文件 VV_AL_3T3_P3.csv 的新列?我希望每个 .tiff 文件都与其文件夹一起使用。
      • 查看编辑。对于写作, csv.writer 通常会让你写出值数组。因此,只需计算每行的所有值,并将它们写成一个数组。
      • 我编辑了这个问题,希望现在更清楚。我获得了两列,一列带有路径,另一列带有所属类,但它们不适合该列的其余部分,如 Image_File、Particle ID、Diameter 等。如果打扰到您,我深表歉意,非常感谢您的帮助,这有助于我了解更多有关 Python 的信息。
      猜你喜欢
      • 2014-05-20
      • 2023-01-02
      • 2015-03-30
      • 1970-01-01
      • 2023-01-16
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      相关资源
      最近更新 更多